initial
This commit is contained in:
1
thirdparty/clang/copy.bat
vendored
Normal file
1
thirdparty/clang/copy.bat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
python copy_includes\copy_includes.py
|
||||
72
thirdparty/clang/copy_includes/copy_includes.py
vendored
Normal file
72
thirdparty/clang/copy_includes/copy_includes.py
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
import glob, sys, os, stat, shutil
|
||||
|
||||
g_nFilesCopied = 0
|
||||
g_nFilesAdded = 0
|
||||
g_nFilesSkipped = 0
|
||||
|
||||
def IsSame( a, b ):
|
||||
return False
|
||||
if a.st_size == b.st_size:
|
||||
if a.st_mtime == b.st_mtime:
|
||||
return True #perhaps we need to actually compare the files??
|
||||
if abs( a.st_mtime - b.st_mtime ) < 1: # may not be runnable on all platforms, but runs fine on windows python 2.6+
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Copy(fromDir, toDir, extensions):
|
||||
global g_nFilesCopied
|
||||
global g_nFilesAdded
|
||||
global g_nFilesSkipped
|
||||
if( toDir == "" ):
|
||||
toDir = os.getcwd()
|
||||
toDir = os.path.abspath( toDir )
|
||||
fromDir = os.path.abspath( fromDir )
|
||||
for root, subFolders, files in os.walk(fromDir):
|
||||
for file in files:
|
||||
if os.path.splitext(file)[1][1:].strip() in extensions and root[:len(fromDir)]==fromDir:
|
||||
fromFile = os.path.join(root, file)
|
||||
fromFileStat = os.stat( fromFile )
|
||||
toFile = os.path.join(toDir,root[len(fromDir)+1:],file)
|
||||
p4AddNeeded = True
|
||||
if( os.path.isfile( toFile ) ): #file exists already, if it's the same file, there's no need to copy anything
|
||||
p4AddNeeded = False
|
||||
toFileStat = os.stat( toFile )
|
||||
|
||||
if( IsSame( toFileStat, fromFileStat ) ):
|
||||
g_nFilesSkipped += 1
|
||||
continue
|
||||
if not( toFileStat.st_mode & stat.S_IWRITE ):
|
||||
os.system( "p4 edit " + toFile )
|
||||
|
||||
if os.path.exists( os.path.dirname( toFile ) ):
|
||||
if not os.path.isdir( os.path.dirname( toFile ) ):
|
||||
print "This is not a dir. Expected a dir: " + os.path.dirname( toFile )
|
||||
sys.exit(-1)
|
||||
else:
|
||||
os.makedirs( os.path.dirname( toFile ) )
|
||||
|
||||
#print fromFile + " -> " + toFile
|
||||
shutil.copyfile( fromFile, toFile )
|
||||
os.utime( toFile, ( fromFileStat.st_atime, fromFileStat.st_mtime ) )
|
||||
if p4AddNeeded:
|
||||
g_nFilesAdded += 1
|
||||
os.system( "p4 add " + toFile )
|
||||
g_nFilesCopied += 1
|
||||
|
||||
extInc = ["h","inc","inl","gen","def"]
|
||||
extLib = ["lib","pdb","def"]
|
||||
|
||||
Copy( "f:/L/llvm.build64/tools/clang/include", "include/win64", extInc )
|
||||
Copy( "f:/L/llvm.build64/include", "include/win64", extInc )
|
||||
Copy( "f:/L/llvm.build/tools/clang/include", "include/win32", extInc )
|
||||
Copy( "f:/L/llvm.build/include", "include/win32", extInc )
|
||||
Copy( "f:/L/llvm/include", "include", extInc )
|
||||
Copy( "f:/L/llvm/tools/clang/include", "include", extInc )
|
||||
Copy( "f:/L/llvm.build64/lib/Debug", "lib/win64/Debug", extLib )
|
||||
Copy( "f:/L/llvm.build64/lib/RelWithDebInfo", "lib/win64/Release", extLib )
|
||||
Copy( "f:/L/llvm.build/lib/Debug", "lib/win32/Debug", extLib )
|
||||
Copy( "f:/L/llvm.build/lib/RelWithDebInfo", "lib/win32/Release", extLib )
|
||||
|
||||
|
||||
print "Files copied: %d, added: %d, skipped: %d" % ( g_nFilesCopied, g_nFilesAdded, g_nFilesSkipped )
|
||||
36
thirdparty/clang/copy_includes/copy_includes.pyproj
vendored
Normal file
36
thirdparty/clang/copy_includes/copy_includes.pyproj
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{715c6bff-399a-41b5-9ad8-14d4414cd5b6}</ProjectGuid>
|
||||
<ProjectHome>.</ProjectHome>
|
||||
<StartupFile>copy_includes.py</StartupFile>
|
||||
<SearchPath>
|
||||
</SearchPath>
|
||||
<WorkingDirectory>..</WorkingDirectory>
|
||||
<OutputPath>.</OutputPath>
|
||||
<Name>copy_includes</Name>
|
||||
<RootNamespace>copy_includes</RootNamespace>
|
||||
<IsWindowsApplication>False</IsWindowsApplication>
|
||||
<InterpreterId>2af0f10d-7135-4994-9156-5d01c9c11b7e</InterpreterId>
|
||||
<InterpreterVersion>2.6</InterpreterVersion>
|
||||
<LaunchProvider>Standard Python launcher</LaunchProvider>
|
||||
<CommandLineArguments>
|
||||
</CommandLineArguments>
|
||||
<InterpreterPath />
|
||||
<InterpreterArguments />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="copy_includes.py" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
|
||||
</Project>
|
||||
995
thirdparty/clang/copy_includes/include/win64/clang/AST/AttrDump.inc
vendored
Normal file
995
thirdparty/clang/copy_includes/include/win64/clang/AST/AttrDump.inc
vendored
Normal file
@@ -0,0 +1,995 @@
|
||||
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|*Attribute dumper *|
|
||||
|* *|
|
||||
|* Automatically generated file, do not edit! *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
switch (A->getKind()) {
|
||||
default:
|
||||
llvm_unreachable("Unknown attribute kind!");
|
||||
break;
|
||||
case attr::AcquiredAfter: {
|
||||
const AcquiredAfterAttr *SA = cast<AcquiredAfterAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (AcquiredAfterAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::AcquiredBefore: {
|
||||
const AcquiredBeforeAttr *SA = cast<AcquiredBeforeAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (AcquiredBeforeAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Alias: {
|
||||
const AliasAttr *SA = cast<AliasAttr>(A);
|
||||
OS << " \"" << SA->getAliasee() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::AlignMac68k: {
|
||||
break;
|
||||
}
|
||||
case attr::Aligned: {
|
||||
const AlignedAttr *SA = cast<AlignedAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
if (SA->isAlignmentExpr()) {
|
||||
lastChild();
|
||||
dumpStmt(SA->getAlignmentExpr());
|
||||
} else
|
||||
dumpType(SA->getAlignmentType()->getType());
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::AllocSize: {
|
||||
const AllocSizeAttr *SA = cast<AllocSizeAttr>(A);
|
||||
for (AllocSizeAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I)
|
||||
OS << " " << *I;
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::AlwaysInline: {
|
||||
break;
|
||||
}
|
||||
case attr::AnalyzerNoReturn: {
|
||||
break;
|
||||
}
|
||||
case attr::Annotate: {
|
||||
const AnnotateAttr *SA = cast<AnnotateAttr>(A);
|
||||
OS << " \"" << SA->getAnnotation() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ArcWeakrefUnavailable: {
|
||||
break;
|
||||
}
|
||||
case attr::ArgumentWithTypeTag: {
|
||||
const ArgumentWithTypeTagAttr *SA = cast<ArgumentWithTypeTagAttr>(A);
|
||||
OS << " " << SA->getArgumentKind()->getName();
|
||||
OS << " " << SA->getArgumentIdx();
|
||||
OS << " " << SA->getTypeTagIdx();
|
||||
if (SA->getIsPointer()) OS << " IsPointer";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::AsmLabel: {
|
||||
const AsmLabelAttr *SA = cast<AsmLabelAttr>(A);
|
||||
OS << " \"" << SA->getLabel() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Availability: {
|
||||
const AvailabilityAttr *SA = cast<AvailabilityAttr>(A);
|
||||
OS << " " << SA->getPlatform()->getName();
|
||||
OS << " " << SA->getIntroduced();
|
||||
OS << " " << SA->getDeprecated();
|
||||
OS << " " << SA->getObsoleted();
|
||||
if (SA->getUnavailable()) OS << " Unavailable";
|
||||
OS << " \"" << SA->getMessage() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false || false || false || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false || false || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Blocks: {
|
||||
const BlocksAttr *SA = cast<BlocksAttr>(A);
|
||||
switch(SA->getType()) {
|
||||
case BlocksAttr::ByRef:
|
||||
OS << " ByRef";
|
||||
break;
|
||||
}
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::C11NoReturn: {
|
||||
break;
|
||||
}
|
||||
case attr::CDecl: {
|
||||
break;
|
||||
}
|
||||
case attr::CFAuditedTransfer: {
|
||||
break;
|
||||
}
|
||||
case attr::CFConsumed: {
|
||||
break;
|
||||
}
|
||||
case attr::CFReturnsNotRetained: {
|
||||
break;
|
||||
}
|
||||
case attr::CFReturnsRetained: {
|
||||
break;
|
||||
}
|
||||
case attr::CFUnknownTransfer: {
|
||||
break;
|
||||
}
|
||||
case attr::CUDAConstant: {
|
||||
break;
|
||||
}
|
||||
case attr::CUDADevice: {
|
||||
break;
|
||||
}
|
||||
case attr::CUDAGlobal: {
|
||||
break;
|
||||
}
|
||||
case attr::CUDAHost: {
|
||||
break;
|
||||
}
|
||||
case attr::CUDALaunchBounds: {
|
||||
const CUDALaunchBoundsAttr *SA = cast<CUDALaunchBoundsAttr>(A);
|
||||
OS << " " << SA->getMaxThreads();
|
||||
OS << " " << SA->getMinBlocks();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::CUDAShared: {
|
||||
break;
|
||||
}
|
||||
case attr::CXX11NoReturn: {
|
||||
break;
|
||||
}
|
||||
case attr::CarriesDependency: {
|
||||
break;
|
||||
}
|
||||
case attr::Cleanup: {
|
||||
const CleanupAttr *SA = cast<CleanupAttr>(A);
|
||||
OS << " ";
|
||||
dumpBareDeclRef(SA->getFunctionDecl());
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Cold: {
|
||||
break;
|
||||
}
|
||||
case attr::Common: {
|
||||
break;
|
||||
}
|
||||
case attr::Const: {
|
||||
break;
|
||||
}
|
||||
case attr::Constructor: {
|
||||
const ConstructorAttr *SA = cast<ConstructorAttr>(A);
|
||||
OS << " " << SA->getPriority();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::DLLExport: {
|
||||
break;
|
||||
}
|
||||
case attr::DLLImport: {
|
||||
break;
|
||||
}
|
||||
case attr::Deprecated: {
|
||||
const DeprecatedAttr *SA = cast<DeprecatedAttr>(A);
|
||||
OS << " \"" << SA->getMessage() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Destructor: {
|
||||
const DestructorAttr *SA = cast<DestructorAttr>(A);
|
||||
OS << " " << SA->getPriority();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Endian: {
|
||||
const EndianAttr *SA = cast<EndianAttr>(A);
|
||||
OS << " " << SA->getPlatform()->getName();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ExclusiveLockFunction: {
|
||||
const ExclusiveLockFunctionAttr *SA = cast<ExclusiveLockFunctionAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (ExclusiveLockFunctionAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ExclusiveLocksRequired: {
|
||||
const ExclusiveLocksRequiredAttr *SA = cast<ExclusiveLocksRequiredAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (ExclusiveLocksRequiredAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ExclusiveTrylockFunction: {
|
||||
const ExclusiveTrylockFunctionAttr *SA = cast<ExclusiveTrylockFunctionAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || SA->args_begin() != SA->args_end();
|
||||
setMoreChildren(MoreChildren);
|
||||
lastChild();
|
||||
dumpStmt(SA->getSuccessValue());
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (ExclusiveTrylockFunctionAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::FallThrough: {
|
||||
break;
|
||||
}
|
||||
case attr::FastCall: {
|
||||
break;
|
||||
}
|
||||
case attr::Final: {
|
||||
break;
|
||||
}
|
||||
case attr::ForceInline: {
|
||||
break;
|
||||
}
|
||||
case attr::Format: {
|
||||
const FormatAttr *SA = cast<FormatAttr>(A);
|
||||
OS << " \"" << SA->getType() << "\"";
|
||||
OS << " " << SA->getFormatIdx();
|
||||
OS << " " << SA->getFirstArg();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::FormatArg: {
|
||||
const FormatArgAttr *SA = cast<FormatArgAttr>(A);
|
||||
OS << " " << SA->getFormatIdx();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::GNUInline: {
|
||||
break;
|
||||
}
|
||||
case attr::GuardedBy: {
|
||||
const GuardedByAttr *SA = cast<GuardedByAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
lastChild();
|
||||
dumpStmt(SA->getArg());
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::GuardedVar: {
|
||||
break;
|
||||
}
|
||||
case attr::Hot: {
|
||||
break;
|
||||
}
|
||||
case attr::IBAction: {
|
||||
break;
|
||||
}
|
||||
case attr::IBOutlet: {
|
||||
break;
|
||||
}
|
||||
case attr::IBOutletCollection: {
|
||||
const IBOutletCollectionAttr *SA = cast<IBOutletCollectionAttr>(A);
|
||||
OS << " " << SA->getInterface().getAsString();
|
||||
OS << " ";
|
||||
SA->getInterfaceLoc().print(OS, *SM);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::InitPriority: {
|
||||
const InitPriorityAttr *SA = cast<InitPriorityAttr>(A);
|
||||
OS << " " << SA->getPriority();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::IntelOclBicc: {
|
||||
break;
|
||||
}
|
||||
case attr::LockReturned: {
|
||||
const LockReturnedAttr *SA = cast<LockReturnedAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
lastChild();
|
||||
dumpStmt(SA->getArg());
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Lockable: {
|
||||
break;
|
||||
}
|
||||
case attr::LocksExcluded: {
|
||||
const LocksExcludedAttr *SA = cast<LocksExcludedAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (LocksExcludedAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::MBlazeInterruptHandler: {
|
||||
break;
|
||||
}
|
||||
case attr::MBlazeSaveVolatiles: {
|
||||
break;
|
||||
}
|
||||
case attr::MSP430Interrupt: {
|
||||
const MSP430InterruptAttr *SA = cast<MSP430InterruptAttr>(A);
|
||||
OS << " " << SA->getNumber();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Malloc: {
|
||||
break;
|
||||
}
|
||||
case attr::MaxFieldAlignment: {
|
||||
const MaxFieldAlignmentAttr *SA = cast<MaxFieldAlignmentAttr>(A);
|
||||
OS << " " << SA->getAlignment();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::MayAlias: {
|
||||
break;
|
||||
}
|
||||
case attr::MinSize: {
|
||||
break;
|
||||
}
|
||||
case attr::Mips16: {
|
||||
break;
|
||||
}
|
||||
case attr::MsProperty: {
|
||||
break;
|
||||
}
|
||||
case attr::MsStruct: {
|
||||
break;
|
||||
}
|
||||
case attr::MultipleInheritance: {
|
||||
break;
|
||||
}
|
||||
case attr::NSBridged: {
|
||||
const NSBridgedAttr *SA = cast<NSBridgedAttr>(A);
|
||||
OS << " " << SA->getBridgedType()->getName();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::NSConsumed: {
|
||||
break;
|
||||
}
|
||||
case attr::NSConsumesSelf: {
|
||||
break;
|
||||
}
|
||||
case attr::NSReturnsAutoreleased: {
|
||||
break;
|
||||
}
|
||||
case attr::NSReturnsNotRetained: {
|
||||
break;
|
||||
}
|
||||
case attr::NSReturnsRetained: {
|
||||
break;
|
||||
}
|
||||
case attr::Naked: {
|
||||
break;
|
||||
}
|
||||
case attr::NoCommon: {
|
||||
break;
|
||||
}
|
||||
case attr::NoDebug: {
|
||||
break;
|
||||
}
|
||||
case attr::NoInline: {
|
||||
break;
|
||||
}
|
||||
case attr::NoInstrumentFunction: {
|
||||
break;
|
||||
}
|
||||
case attr::NoMips16: {
|
||||
break;
|
||||
}
|
||||
case attr::NoReturn: {
|
||||
break;
|
||||
}
|
||||
case attr::NoSanitizeAddress: {
|
||||
break;
|
||||
}
|
||||
case attr::NoSanitizeMemory: {
|
||||
break;
|
||||
}
|
||||
case attr::NoSanitizeThread: {
|
||||
break;
|
||||
}
|
||||
case attr::NoThreadSafetyAnalysis: {
|
||||
break;
|
||||
}
|
||||
case attr::NoThrow: {
|
||||
break;
|
||||
}
|
||||
case attr::NonNull: {
|
||||
const NonNullAttr *SA = cast<NonNullAttr>(A);
|
||||
for (NonNullAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I)
|
||||
OS << " " << *I;
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ObjCException: {
|
||||
break;
|
||||
}
|
||||
case attr::ObjCMethodFamily: {
|
||||
const ObjCMethodFamilyAttr *SA = cast<ObjCMethodFamilyAttr>(A);
|
||||
switch(SA->getFamily()) {
|
||||
case ObjCMethodFamilyAttr::OMF_None:
|
||||
OS << " OMF_None";
|
||||
break;
|
||||
case ObjCMethodFamilyAttr::OMF_alloc:
|
||||
OS << " OMF_alloc";
|
||||
break;
|
||||
case ObjCMethodFamilyAttr::OMF_copy:
|
||||
OS << " OMF_copy";
|
||||
break;
|
||||
case ObjCMethodFamilyAttr::OMF_init:
|
||||
OS << " OMF_init";
|
||||
break;
|
||||
case ObjCMethodFamilyAttr::OMF_mutableCopy:
|
||||
OS << " OMF_mutableCopy";
|
||||
break;
|
||||
case ObjCMethodFamilyAttr::OMF_new:
|
||||
OS << " OMF_new";
|
||||
break;
|
||||
}
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ObjCNSObject: {
|
||||
break;
|
||||
}
|
||||
case attr::ObjCPreciseLifetime: {
|
||||
break;
|
||||
}
|
||||
case attr::ObjCRequiresPropertyDefs: {
|
||||
break;
|
||||
}
|
||||
case attr::ObjCRequiresSuper: {
|
||||
break;
|
||||
}
|
||||
case attr::ObjCReturnsInnerPointer: {
|
||||
break;
|
||||
}
|
||||
case attr::ObjCRootClass: {
|
||||
break;
|
||||
}
|
||||
case attr::OpenCLImageAccess: {
|
||||
const OpenCLImageAccessAttr *SA = cast<OpenCLImageAccessAttr>(A);
|
||||
OS << " " << SA->getAccess();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::OpenCLKernel: {
|
||||
break;
|
||||
}
|
||||
case attr::Overloadable: {
|
||||
break;
|
||||
}
|
||||
case attr::Override: {
|
||||
break;
|
||||
}
|
||||
case attr::Ownership: {
|
||||
const OwnershipAttr *SA = cast<OwnershipAttr>(A);
|
||||
switch(SA->getOwnKind()) {
|
||||
case OwnershipAttr::Holds:
|
||||
OS << " Holds";
|
||||
break;
|
||||
case OwnershipAttr::Returns:
|
||||
OS << " Returns";
|
||||
break;
|
||||
case OwnershipAttr::Takes:
|
||||
OS << " Takes";
|
||||
break;
|
||||
}
|
||||
OS << " \"" << SA->getModule() << "\"";
|
||||
for (OwnershipAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I)
|
||||
OS << " " << *I;
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Packed: {
|
||||
break;
|
||||
}
|
||||
case attr::Pascal: {
|
||||
break;
|
||||
}
|
||||
case attr::Pcs: {
|
||||
const PcsAttr *SA = cast<PcsAttr>(A);
|
||||
switch(SA->getPCS()) {
|
||||
case PcsAttr::AAPCS:
|
||||
OS << " AAPCS";
|
||||
break;
|
||||
case PcsAttr::AAPCS_VFP:
|
||||
OS << " AAPCS_VFP";
|
||||
break;
|
||||
}
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::PnaclCall: {
|
||||
break;
|
||||
}
|
||||
case attr::PtGuardedBy: {
|
||||
const PtGuardedByAttr *SA = cast<PtGuardedByAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
lastChild();
|
||||
dumpStmt(SA->getArg());
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::PtGuardedVar: {
|
||||
break;
|
||||
}
|
||||
case attr::Ptr32: {
|
||||
break;
|
||||
}
|
||||
case attr::Ptr64: {
|
||||
break;
|
||||
}
|
||||
case attr::Pure: {
|
||||
break;
|
||||
}
|
||||
case attr::Regparm: {
|
||||
const RegparmAttr *SA = cast<RegparmAttr>(A);
|
||||
OS << " " << SA->getNumParams();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ReqdWorkGroupSize: {
|
||||
const ReqdWorkGroupSizeAttr *SA = cast<ReqdWorkGroupSizeAttr>(A);
|
||||
OS << " " << SA->getXDim();
|
||||
OS << " " << SA->getYDim();
|
||||
OS << " " << SA->getZDim();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ReturnsTwice: {
|
||||
break;
|
||||
}
|
||||
case attr::ScopedLockable: {
|
||||
break;
|
||||
}
|
||||
case attr::Section: {
|
||||
const SectionAttr *SA = cast<SectionAttr>(A);
|
||||
OS << " \"" << SA->getName() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Sentinel: {
|
||||
const SentinelAttr *SA = cast<SentinelAttr>(A);
|
||||
OS << " " << SA->getSentinel();
|
||||
OS << " " << SA->getNullPos();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::SharedLockFunction: {
|
||||
const SharedLockFunctionAttr *SA = cast<SharedLockFunctionAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (SharedLockFunctionAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::SharedLocksRequired: {
|
||||
const SharedLocksRequiredAttr *SA = cast<SharedLocksRequiredAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (SharedLocksRequiredAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::SharedTrylockFunction: {
|
||||
const SharedTrylockFunctionAttr *SA = cast<SharedTrylockFunctionAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || SA->args_begin() != SA->args_end();
|
||||
setMoreChildren(MoreChildren);
|
||||
lastChild();
|
||||
dumpStmt(SA->getSuccessValue());
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (SharedTrylockFunctionAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::SingleInheritance: {
|
||||
break;
|
||||
}
|
||||
case attr::StdCall: {
|
||||
break;
|
||||
}
|
||||
case attr::TLSModel: {
|
||||
const TLSModelAttr *SA = cast<TLSModelAttr>(A);
|
||||
OS << " \"" << SA->getModel() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::ThisCall: {
|
||||
break;
|
||||
}
|
||||
case attr::TransparentUnion: {
|
||||
break;
|
||||
}
|
||||
case attr::TypeTagForDatatype: {
|
||||
const TypeTagForDatatypeAttr *SA = cast<TypeTagForDatatypeAttr>(A);
|
||||
OS << " " << SA->getArgumentKind()->getName();
|
||||
OS << " " << SA->getMatchingCType().getAsString();
|
||||
if (SA->getLayoutCompatible()) OS << " LayoutCompatible";
|
||||
if (SA->getMustBeNull()) OS << " MustBeNull";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::TypeVisibility: {
|
||||
const TypeVisibilityAttr *SA = cast<TypeVisibilityAttr>(A);
|
||||
switch(SA->getVisibility()) {
|
||||
case TypeVisibilityAttr::Default:
|
||||
OS << " Default";
|
||||
break;
|
||||
case TypeVisibilityAttr::Hidden:
|
||||
OS << " Hidden";
|
||||
break;
|
||||
case TypeVisibilityAttr::Protected:
|
||||
OS << " Protected";
|
||||
break;
|
||||
}
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::Unavailable: {
|
||||
const UnavailableAttr *SA = cast<UnavailableAttr>(A);
|
||||
OS << " \"" << SA->getMessage() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::UnlockFunction: {
|
||||
const UnlockFunctionAttr *SA = cast<UnlockFunctionAttr>(A);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
for (UnlockFunctionAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
|
||||
if (I + 1 == E)
|
||||
lastChild();
|
||||
dumpStmt(*I);
|
||||
}
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::UnspecifiedInheritance: {
|
||||
break;
|
||||
}
|
||||
case attr::Unused: {
|
||||
break;
|
||||
}
|
||||
case attr::Used: {
|
||||
break;
|
||||
}
|
||||
case attr::Uuid: {
|
||||
const UuidAttr *SA = cast<UuidAttr>(A);
|
||||
OS << " \"" << SA->getGuid() << "\"";
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::VecReturn: {
|
||||
break;
|
||||
}
|
||||
case attr::VecTypeHint: {
|
||||
const VecTypeHintAttr *SA = cast<VecTypeHintAttr>(A);
|
||||
OS << " " << SA->getTypeHint().getAsString();
|
||||
OS << " ";
|
||||
SA->getTypeLoc().print(OS, *SM);
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::VirtualInheritance: {
|
||||
break;
|
||||
}
|
||||
case attr::Visibility: {
|
||||
const VisibilityAttr *SA = cast<VisibilityAttr>(A);
|
||||
switch(SA->getVisibility()) {
|
||||
case VisibilityAttr::Default:
|
||||
OS << " Default";
|
||||
break;
|
||||
case VisibilityAttr::Hidden:
|
||||
OS << " Hidden";
|
||||
break;
|
||||
case VisibilityAttr::Protected:
|
||||
OS << " Protected";
|
||||
break;
|
||||
}
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::WarnUnusedResult: {
|
||||
break;
|
||||
}
|
||||
case attr::Weak: {
|
||||
break;
|
||||
}
|
||||
case attr::WeakImport: {
|
||||
break;
|
||||
}
|
||||
case attr::WeakRef: {
|
||||
break;
|
||||
}
|
||||
case attr::Win64: {
|
||||
break;
|
||||
}
|
||||
case attr::WorkGroupSizeHint: {
|
||||
const WorkGroupSizeHintAttr *SA = cast<WorkGroupSizeHintAttr>(A);
|
||||
OS << " " << SA->getXDim();
|
||||
OS << " " << SA->getYDim();
|
||||
OS << " " << SA->getZDim();
|
||||
bool OldMoreChildren = hasMoreChildren();
|
||||
bool MoreChildren = OldMoreChildren;
|
||||
MoreChildren = OldMoreChildren || false || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren || false;
|
||||
setMoreChildren(MoreChildren);
|
||||
MoreChildren = OldMoreChildren;
|
||||
setMoreChildren(MoreChildren);
|
||||
setMoreChildren(OldMoreChildren);
|
||||
break;
|
||||
}
|
||||
case attr::X86ForceAlignArgPointer: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
2661
thirdparty/clang/copy_includes/include/win64/clang/AST/AttrImpl.inc
vendored
Normal file
2661
thirdparty/clang/copy_includes/include/win64/clang/AST/AttrImpl.inc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3755
thirdparty/clang/copy_includes/include/win64/clang/AST/Attrs.inc
vendored
Normal file
3755
thirdparty/clang/copy_includes/include/win64/clang/AST/Attrs.inc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
730
thirdparty/clang/copy_includes/include/win64/clang/AST/CommentCommandInfo.inc
vendored
Normal file
730
thirdparty/clang/copy_includes/include/win64/clang/AST/CommentCommandInfo.inc
vendored
Normal file
@@ -0,0 +1,730 @@
|
||||
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|*A list of commands useable in documentation comments *|
|
||||
|* *|
|
||||
|* Automatically generated file, do not edit! *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
namespace {
|
||||
const CommandInfo Commands[] = {
|
||||
{ "a", "", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "abstract", "", 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "addtogroup", "", 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "arg", "", 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "attention", "", 4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "author", "", 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "authors", "", 6, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "b", "", 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "brief", "", 8, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "bug", "", 9, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "c", "", 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "callback", "", 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
|
||||
{ "category", "", 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "class", "", 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
|
||||
{ "classdesign", "", 14, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "coclass", "", 15, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "code", "endcode", 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endcode", "", 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "const", "", 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "constant", "", 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "copyright", "", 20, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "date", "", 21, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "defgroup", "", 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "dependency", "", 23, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "deprecated", "", 24, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "details", "", 25, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "discussion", "", 26, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "dot", "enddot", 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "enddot", "", 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "e", "", 29, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "em", "", 30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "enum", "", 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "f{", "f}", 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "f}", "", 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "f[", "f]", 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "f]", "", 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "f$", "f$", 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "fn", "", 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "function", "", 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
|
||||
{ "functiongroup", "", 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
|
||||
{ "headerfile", "", 40, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "helper", "", 41, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "helperclass", "", 42, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "helps", "", 43, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "htmlonly", "endhtmlonly", 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endhtmlonly", "", 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "ingroup", "", 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "instancesize", "", 47, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "interface", "", 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
|
||||
{ "invariant", "", 49, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "latexonly", "endlatexonly", 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endlatexonly", "", 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "li", "", 52, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "link", "/link", 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "/link", "", 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "mainpage", "", 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "manonly", "endmanonly", 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endmanonly", "", 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "method", "", 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
|
||||
{ "methodgroup", "", 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
|
||||
{ "msc", "endmsc", 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endmsc", "", 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "name", "", 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "namespace", "", 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "note", "", 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "overload", "", 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "ownership", "", 66, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "p", "", 67, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "paragraph", "", 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "param", "", 69, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "performance", "", 70, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "post", "", 71, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "pre", "", 72, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "property", "", 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "protocol", "", 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
|
||||
{ "ref", "", 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "remark", "", 76, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "remarks", "", 77, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "result", "", 78, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "return", "", 79, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "returns", "", 80, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "rtfonly", "endrtfonly", 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endrtfonly", "", 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "sa", "", 83, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "section", "", 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "security", "", 85, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "see", "", 86, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "seealso", "", 87, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "short", "", 88, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "since", "", 89, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "struct", "", 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
|
||||
{ "subpage", "", 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "subsection", "", 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "subsubsection", "", 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "superclass", "", 94, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
|
||||
{ "template", "", 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "templatefield", "", 96, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "textblock", "/textblock", 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "/textblock", "", 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "todo", "", 99, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "tparam", "", 100, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "typedef", "", 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "union", "", 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
|
||||
{ "var", "", 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
|
||||
{ "verbatim", "endverbatim", 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endverbatim", "", 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ "version", "", 106, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "warning", "", 107, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "weakgroup", "", 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
{ "xmlonly", "endxmlonly", 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ "endxmlonly", "", 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
} // unnamed namespace
|
||||
|
||||
const CommandInfo *CommandTraits::getBuiltinCommandInfo(
|
||||
StringRef Name) {
|
||||
switch (Name.size()) {
|
||||
default: break;
|
||||
case 1: // 5 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'a': // 1 string to match.
|
||||
return &Commands[0]; // "a"
|
||||
case 'b': // 1 string to match.
|
||||
return &Commands[7]; // "b"
|
||||
case 'c': // 1 string to match.
|
||||
return &Commands[10]; // "c"
|
||||
case 'e': // 1 string to match.
|
||||
return &Commands[29]; // "e"
|
||||
case 'p': // 1 string to match.
|
||||
return &Commands[67]; // "p"
|
||||
}
|
||||
break;
|
||||
case 2: // 9 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'e': // 1 string to match.
|
||||
if (Name[1] != 'm')
|
||||
break;
|
||||
return &Commands[30]; // "em"
|
||||
case 'f': // 6 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case '$': // 1 string to match.
|
||||
return &Commands[36]; // "f$"
|
||||
case '[': // 1 string to match.
|
||||
return &Commands[34]; // "f["
|
||||
case ']': // 1 string to match.
|
||||
return &Commands[35]; // "f]"
|
||||
case 'n': // 1 string to match.
|
||||
return &Commands[37]; // "fn"
|
||||
case '{': // 1 string to match.
|
||||
return &Commands[32]; // "f{"
|
||||
case '}': // 1 string to match.
|
||||
return &Commands[33]; // "f}"
|
||||
}
|
||||
break;
|
||||
case 'l': // 1 string to match.
|
||||
if (Name[1] != 'i')
|
||||
break;
|
||||
return &Commands[52]; // "li"
|
||||
case 's': // 1 string to match.
|
||||
if (Name[1] != 'a')
|
||||
break;
|
||||
return &Commands[83]; // "sa"
|
||||
}
|
||||
break;
|
||||
case 3: // 8 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'a': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "rg", 2))
|
||||
break;
|
||||
return &Commands[3]; // "arg"
|
||||
case 'b': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ug", 2))
|
||||
break;
|
||||
return &Commands[9]; // "bug"
|
||||
case 'd': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ot", 2))
|
||||
break;
|
||||
return &Commands[27]; // "dot"
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "sc", 2))
|
||||
break;
|
||||
return &Commands[60]; // "msc"
|
||||
case 'p': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "re", 2))
|
||||
break;
|
||||
return &Commands[72]; // "pre"
|
||||
case 'r': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ef", 2))
|
||||
break;
|
||||
return &Commands[75]; // "ref"
|
||||
case 's': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ee", 2))
|
||||
break;
|
||||
return &Commands[86]; // "see"
|
||||
case 'v': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ar", 2))
|
||||
break;
|
||||
return &Commands[103]; // "var"
|
||||
}
|
||||
break;
|
||||
case 4: // 8 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'c': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ode", 3))
|
||||
break;
|
||||
return &Commands[16]; // "code"
|
||||
case 'd': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ate", 3))
|
||||
break;
|
||||
return &Commands[21]; // "date"
|
||||
case 'e': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "num", 3))
|
||||
break;
|
||||
return &Commands[31]; // "enum"
|
||||
case 'l': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ink", 3))
|
||||
break;
|
||||
return &Commands[53]; // "link"
|
||||
case 'n': // 2 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case 'a': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "me", 2))
|
||||
break;
|
||||
return &Commands[62]; // "name"
|
||||
case 'o': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "te", 2))
|
||||
break;
|
||||
return &Commands[64]; // "note"
|
||||
}
|
||||
break;
|
||||
case 'p': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ost", 3))
|
||||
break;
|
||||
return &Commands[71]; // "post"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "odo", 3))
|
||||
break;
|
||||
return &Commands[99]; // "todo"
|
||||
}
|
||||
break;
|
||||
case 5: // 9 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case '/': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "link", 4))
|
||||
break;
|
||||
return &Commands[54]; // "/link"
|
||||
case 'b': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "rief", 4))
|
||||
break;
|
||||
return &Commands[8]; // "brief"
|
||||
case 'c': // 2 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case 'l': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "ass", 3))
|
||||
break;
|
||||
return &Commands[13]; // "class"
|
||||
case 'o': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "nst", 3))
|
||||
break;
|
||||
return &Commands[18]; // "const"
|
||||
}
|
||||
break;
|
||||
case 'h': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "elps", 4))
|
||||
break;
|
||||
return &Commands[43]; // "helps"
|
||||
case 'p': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "aram", 4))
|
||||
break;
|
||||
return &Commands[69]; // "param"
|
||||
case 's': // 2 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case 'h': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "ort", 3))
|
||||
break;
|
||||
return &Commands[88]; // "short"
|
||||
case 'i': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "nce", 3))
|
||||
break;
|
||||
return &Commands[89]; // "since"
|
||||
}
|
||||
break;
|
||||
case 'u': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "nion", 4))
|
||||
break;
|
||||
return &Commands[102]; // "union"
|
||||
}
|
||||
break;
|
||||
case 6: // 10 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'a': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "uthor", 5))
|
||||
break;
|
||||
return &Commands[5]; // "author"
|
||||
case 'e': // 2 strings to match.
|
||||
if (memcmp(Name.data()+1, "nd", 2))
|
||||
break;
|
||||
switch (Name[3]) {
|
||||
default: break;
|
||||
case 'd': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "ot", 2))
|
||||
break;
|
||||
return &Commands[28]; // "enddot"
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "sc", 2))
|
||||
break;
|
||||
return &Commands[61]; // "endmsc"
|
||||
}
|
||||
break;
|
||||
case 'h': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "elper", 5))
|
||||
break;
|
||||
return &Commands[41]; // "helper"
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ethod", 5))
|
||||
break;
|
||||
return &Commands[58]; // "method"
|
||||
case 'r': // 3 strings to match.
|
||||
if (Name[1] != 'e')
|
||||
break;
|
||||
switch (Name[2]) {
|
||||
default: break;
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "ark", 3))
|
||||
break;
|
||||
return &Commands[76]; // "remark"
|
||||
case 's': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "ult", 3))
|
||||
break;
|
||||
return &Commands[78]; // "result"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "urn", 3))
|
||||
break;
|
||||
return &Commands[79]; // "return"
|
||||
}
|
||||
break;
|
||||
case 's': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "truct", 5))
|
||||
break;
|
||||
return &Commands[90]; // "struct"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "param", 5))
|
||||
break;
|
||||
return &Commands[100]; // "tparam"
|
||||
}
|
||||
break;
|
||||
case 7: // 16 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'a': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "uthors", 6))
|
||||
break;
|
||||
return &Commands[6]; // "authors"
|
||||
case 'c': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "oclass", 6))
|
||||
break;
|
||||
return &Commands[15]; // "coclass"
|
||||
case 'd': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "etails", 6))
|
||||
break;
|
||||
return &Commands[25]; // "details"
|
||||
case 'e': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ndcode", 6))
|
||||
break;
|
||||
return &Commands[17]; // "endcode"
|
||||
case 'i': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ngroup", 6))
|
||||
break;
|
||||
return &Commands[46]; // "ingroup"
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "anonly", 6))
|
||||
break;
|
||||
return &Commands[56]; // "manonly"
|
||||
case 'r': // 3 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case 'e': // 2 strings to match.
|
||||
switch (Name[2]) {
|
||||
default: break;
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "arks", 4))
|
||||
break;
|
||||
return &Commands[77]; // "remarks"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "urns", 4))
|
||||
break;
|
||||
return &Commands[80]; // "returns"
|
||||
}
|
||||
break;
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "fonly", 5))
|
||||
break;
|
||||
return &Commands[81]; // "rtfonly"
|
||||
}
|
||||
break;
|
||||
case 's': // 3 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case 'e': // 2 strings to match.
|
||||
switch (Name[2]) {
|
||||
default: break;
|
||||
case 'c': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "tion", 4))
|
||||
break;
|
||||
return &Commands[84]; // "section"
|
||||
case 'e': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "also", 4))
|
||||
break;
|
||||
return &Commands[87]; // "seealso"
|
||||
}
|
||||
break;
|
||||
case 'u': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "bpage", 5))
|
||||
break;
|
||||
return &Commands[91]; // "subpage"
|
||||
}
|
||||
break;
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ypedef", 6))
|
||||
break;
|
||||
return &Commands[101]; // "typedef"
|
||||
case 'v': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ersion", 6))
|
||||
break;
|
||||
return &Commands[106]; // "version"
|
||||
case 'w': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "arning", 6))
|
||||
break;
|
||||
return &Commands[107]; // "warning"
|
||||
case 'x': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "mlonly", 6))
|
||||
break;
|
||||
return &Commands[109]; // "xmlonly"
|
||||
}
|
||||
break;
|
||||
case 8: // 14 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'a': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "bstract", 7))
|
||||
break;
|
||||
return &Commands[1]; // "abstract"
|
||||
case 'c': // 3 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case 'a': // 2 strings to match.
|
||||
switch (Name[2]) {
|
||||
default: break;
|
||||
case 'l': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "lback", 5))
|
||||
break;
|
||||
return &Commands[11]; // "callback"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "egory", 5))
|
||||
break;
|
||||
return &Commands[12]; // "category"
|
||||
}
|
||||
break;
|
||||
case 'o': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "nstant", 6))
|
||||
break;
|
||||
return &Commands[19]; // "constant"
|
||||
}
|
||||
break;
|
||||
case 'd': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "efgroup", 7))
|
||||
break;
|
||||
return &Commands[22]; // "defgroup"
|
||||
case 'f': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "unction", 7))
|
||||
break;
|
||||
return &Commands[38]; // "function"
|
||||
case 'h': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "tmlonly", 7))
|
||||
break;
|
||||
return &Commands[44]; // "htmlonly"
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ainpage", 7))
|
||||
break;
|
||||
return &Commands[55]; // "mainpage"
|
||||
case 'o': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "verload", 7))
|
||||
break;
|
||||
return &Commands[65]; // "overload"
|
||||
case 'p': // 2 strings to match.
|
||||
if (memcmp(Name.data()+1, "ro", 2))
|
||||
break;
|
||||
switch (Name[3]) {
|
||||
default: break;
|
||||
case 'p': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "erty", 4))
|
||||
break;
|
||||
return &Commands[73]; // "property"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "ocol", 4))
|
||||
break;
|
||||
return &Commands[74]; // "protocol"
|
||||
}
|
||||
break;
|
||||
case 's': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ecurity", 7))
|
||||
break;
|
||||
return &Commands[85]; // "security"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "emplate", 7))
|
||||
break;
|
||||
return &Commands[95]; // "template"
|
||||
case 'v': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "erbatim", 7))
|
||||
break;
|
||||
return &Commands[104]; // "verbatim"
|
||||
}
|
||||
break;
|
||||
case 9: // 10 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'a': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ttention", 8))
|
||||
break;
|
||||
return &Commands[4]; // "attention"
|
||||
case 'c': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "opyright", 8))
|
||||
break;
|
||||
return &Commands[20]; // "copyright"
|
||||
case 'i': // 2 strings to match.
|
||||
if (Name[1] != 'n')
|
||||
break;
|
||||
switch (Name[2]) {
|
||||
default: break;
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "erface", 6))
|
||||
break;
|
||||
return &Commands[48]; // "interface"
|
||||
case 'v': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "ariant", 6))
|
||||
break;
|
||||
return &Commands[49]; // "invariant"
|
||||
}
|
||||
break;
|
||||
case 'l': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "atexonly", 8))
|
||||
break;
|
||||
return &Commands[50]; // "latexonly"
|
||||
case 'n': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "amespace", 8))
|
||||
break;
|
||||
return &Commands[63]; // "namespace"
|
||||
case 'o': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "wnership", 8))
|
||||
break;
|
||||
return &Commands[66]; // "ownership"
|
||||
case 'p': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "aragraph", 8))
|
||||
break;
|
||||
return &Commands[68]; // "paragraph"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "extblock", 8))
|
||||
break;
|
||||
return &Commands[97]; // "textblock"
|
||||
case 'w': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "eakgroup", 8))
|
||||
break;
|
||||
return &Commands[108]; // "weakgroup"
|
||||
}
|
||||
break;
|
||||
case 10: // 11 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case '/': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "textblock", 9))
|
||||
break;
|
||||
return &Commands[98]; // "/textblock"
|
||||
case 'a': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ddtogroup", 9))
|
||||
break;
|
||||
return &Commands[2]; // "addtogroup"
|
||||
case 'd': // 3 strings to match.
|
||||
switch (Name[1]) {
|
||||
default: break;
|
||||
case 'e': // 2 strings to match.
|
||||
if (Name[2] != 'p')
|
||||
break;
|
||||
switch (Name[3]) {
|
||||
default: break;
|
||||
case 'e': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "ndency", 6))
|
||||
break;
|
||||
return &Commands[23]; // "dependency"
|
||||
case 'r': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "ecated", 6))
|
||||
break;
|
||||
return &Commands[24]; // "deprecated"
|
||||
}
|
||||
break;
|
||||
case 'i': // 1 string to match.
|
||||
if (memcmp(Name.data()+2, "scussion", 8))
|
||||
break;
|
||||
return &Commands[26]; // "discussion"
|
||||
}
|
||||
break;
|
||||
case 'e': // 3 strings to match.
|
||||
if (memcmp(Name.data()+1, "nd", 2))
|
||||
break;
|
||||
switch (Name[3]) {
|
||||
default: break;
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "anonly", 6))
|
||||
break;
|
||||
return &Commands[57]; // "endmanonly"
|
||||
case 'r': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "tfonly", 6))
|
||||
break;
|
||||
return &Commands[82]; // "endrtfonly"
|
||||
case 'x': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "mlonly", 6))
|
||||
break;
|
||||
return &Commands[110]; // "endxmlonly"
|
||||
}
|
||||
break;
|
||||
case 'h': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "eaderfile", 9))
|
||||
break;
|
||||
return &Commands[40]; // "headerfile"
|
||||
case 's': // 2 strings to match.
|
||||
if (Name[1] != 'u')
|
||||
break;
|
||||
switch (Name[2]) {
|
||||
default: break;
|
||||
case 'b': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "section", 7))
|
||||
break;
|
||||
return &Commands[92]; // "subsection"
|
||||
case 'p': // 1 string to match.
|
||||
if (memcmp(Name.data()+3, "erclass", 7))
|
||||
break;
|
||||
return &Commands[94]; // "superclass"
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 11: // 6 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'c': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "lassdesign", 10))
|
||||
break;
|
||||
return &Commands[14]; // "classdesign"
|
||||
case 'e': // 2 strings to match.
|
||||
if (memcmp(Name.data()+1, "nd", 2))
|
||||
break;
|
||||
switch (Name[3]) {
|
||||
default: break;
|
||||
case 'h': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "tmlonly", 7))
|
||||
break;
|
||||
return &Commands[45]; // "endhtmlonly"
|
||||
case 'v': // 1 string to match.
|
||||
if (memcmp(Name.data()+4, "erbatim", 7))
|
||||
break;
|
||||
return &Commands[105]; // "endverbatim"
|
||||
}
|
||||
break;
|
||||
case 'h': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "elperclass", 10))
|
||||
break;
|
||||
return &Commands[42]; // "helperclass"
|
||||
case 'm': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ethodgroup", 10))
|
||||
break;
|
||||
return &Commands[59]; // "methodgroup"
|
||||
case 'p': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "erformance", 10))
|
||||
break;
|
||||
return &Commands[70]; // "performance"
|
||||
}
|
||||
break;
|
||||
case 12: // 2 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'e': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ndlatexonly", 11))
|
||||
break;
|
||||
return &Commands[51]; // "endlatexonly"
|
||||
case 'i': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "nstancesize", 11))
|
||||
break;
|
||||
return &Commands[47]; // "instancesize"
|
||||
}
|
||||
break;
|
||||
case 13: // 3 strings to match.
|
||||
switch (Name[0]) {
|
||||
default: break;
|
||||
case 'f': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "unctiongroup", 12))
|
||||
break;
|
||||
return &Commands[39]; // "functiongroup"
|
||||
case 's': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "ubsubsection", 12))
|
||||
break;
|
||||
return &Commands[93]; // "subsubsection"
|
||||
case 't': // 1 string to match.
|
||||
if (memcmp(Name.data()+1, "emplatefield", 12))
|
||||
break;
|
||||
return &Commands[96]; // "templatefield"
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
122
thirdparty/clang/copy_includes/include/win64/clang/AST/CommentCommandList.inc
vendored
Normal file
122
thirdparty/clang/copy_includes/include/win64/clang/AST/CommentCommandList.inc
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|*A list of commands useable in documentation comments *|
|
||||
|* *|
|
||||
|* Automatically generated file, do not edit! *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef COMMENT_COMMAND
|
||||
# define COMMENT_COMMAND(NAME)
|
||||
#endif
|
||||
COMMENT_COMMAND(a)
|
||||
COMMENT_COMMAND(abstract)
|
||||
COMMENT_COMMAND(addtogroup)
|
||||
COMMENT_COMMAND(arg)
|
||||
COMMENT_COMMAND(attention)
|
||||
COMMENT_COMMAND(author)
|
||||
COMMENT_COMMAND(authors)
|
||||
COMMENT_COMMAND(b)
|
||||
COMMENT_COMMAND(brief)
|
||||
COMMENT_COMMAND(bug)
|
||||
COMMENT_COMMAND(c)
|
||||
COMMENT_COMMAND(callback)
|
||||
COMMENT_COMMAND(category)
|
||||
COMMENT_COMMAND(class)
|
||||
COMMENT_COMMAND(classdesign)
|
||||
COMMENT_COMMAND(coclass)
|
||||
COMMENT_COMMAND(code)
|
||||
COMMENT_COMMAND(endcode)
|
||||
COMMENT_COMMAND(const)
|
||||
COMMENT_COMMAND(constant)
|
||||
COMMENT_COMMAND(copyright)
|
||||
COMMENT_COMMAND(date)
|
||||
COMMENT_COMMAND(defgroup)
|
||||
COMMENT_COMMAND(dependency)
|
||||
COMMENT_COMMAND(deprecated)
|
||||
COMMENT_COMMAND(details)
|
||||
COMMENT_COMMAND(discussion)
|
||||
COMMENT_COMMAND(dot)
|
||||
COMMENT_COMMAND(enddot)
|
||||
COMMENT_COMMAND(e)
|
||||
COMMENT_COMMAND(em)
|
||||
COMMENT_COMMAND(enum)
|
||||
COMMENT_COMMAND(flbrace)
|
||||
COMMENT_COMMAND(frbrace)
|
||||
COMMENT_COMMAND(flsquare)
|
||||
COMMENT_COMMAND(frsquare)
|
||||
COMMENT_COMMAND(fdollar)
|
||||
COMMENT_COMMAND(fn)
|
||||
COMMENT_COMMAND(function)
|
||||
COMMENT_COMMAND(functiongroup)
|
||||
COMMENT_COMMAND(headerfile)
|
||||
COMMENT_COMMAND(helper)
|
||||
COMMENT_COMMAND(helperclass)
|
||||
COMMENT_COMMAND(helps)
|
||||
COMMENT_COMMAND(htmlonly)
|
||||
COMMENT_COMMAND(endhtmlonly)
|
||||
COMMENT_COMMAND(ingroup)
|
||||
COMMENT_COMMAND(instancesize)
|
||||
COMMENT_COMMAND(interface)
|
||||
COMMENT_COMMAND(invariant)
|
||||
COMMENT_COMMAND(latexonly)
|
||||
COMMENT_COMMAND(endlatexonly)
|
||||
COMMENT_COMMAND(li)
|
||||
COMMENT_COMMAND(link)
|
||||
COMMENT_COMMAND(slashlink)
|
||||
COMMENT_COMMAND(mainpage)
|
||||
COMMENT_COMMAND(manonly)
|
||||
COMMENT_COMMAND(endmanonly)
|
||||
COMMENT_COMMAND(method)
|
||||
COMMENT_COMMAND(methodgroup)
|
||||
COMMENT_COMMAND(msc)
|
||||
COMMENT_COMMAND(endmsc)
|
||||
COMMENT_COMMAND(name)
|
||||
COMMENT_COMMAND(namespace)
|
||||
COMMENT_COMMAND(note)
|
||||
COMMENT_COMMAND(overload)
|
||||
COMMENT_COMMAND(ownership)
|
||||
COMMENT_COMMAND(p)
|
||||
COMMENT_COMMAND(paragraph)
|
||||
COMMENT_COMMAND(param)
|
||||
COMMENT_COMMAND(performance)
|
||||
COMMENT_COMMAND(post)
|
||||
COMMENT_COMMAND(pre)
|
||||
COMMENT_COMMAND(property)
|
||||
COMMENT_COMMAND(protocol)
|
||||
COMMENT_COMMAND(ref)
|
||||
COMMENT_COMMAND(remark)
|
||||
COMMENT_COMMAND(remarks)
|
||||
COMMENT_COMMAND(result)
|
||||
COMMENT_COMMAND(return)
|
||||
COMMENT_COMMAND(returns)
|
||||
COMMENT_COMMAND(rtfonly)
|
||||
COMMENT_COMMAND(endrtfonly)
|
||||
COMMENT_COMMAND(sa)
|
||||
COMMENT_COMMAND(section)
|
||||
COMMENT_COMMAND(security)
|
||||
COMMENT_COMMAND(see)
|
||||
COMMENT_COMMAND(seealso)
|
||||
COMMENT_COMMAND(short)
|
||||
COMMENT_COMMAND(since)
|
||||
COMMENT_COMMAND(struct)
|
||||
COMMENT_COMMAND(subpage)
|
||||
COMMENT_COMMAND(subsection)
|
||||
COMMENT_COMMAND(subsubsection)
|
||||
COMMENT_COMMAND(superclass)
|
||||
COMMENT_COMMAND(template)
|
||||
COMMENT_COMMAND(templatefield)
|
||||
COMMENT_COMMAND(textblock)
|
||||
COMMENT_COMMAND(slashtextblock)
|
||||
COMMENT_COMMAND(todo)
|
||||
COMMENT_COMMAND(tparam)
|
||||
COMMENT_COMMAND(typedef)
|
||||
COMMENT_COMMAND(union)
|
||||
COMMENT_COMMAND(var)
|
||||
COMMENT_COMMAND(verbatim)
|
||||
COMMENT_COMMAND(endverbatim)
|
||||
COMMENT_COMMAND(version)
|
||||
COMMENT_COMMAND(warning)
|
||||
COMMENT_COMMAND(weakgroup)
|
||||
COMMENT_COMMAND(xmlonly)
|
||||
COMMENT_COMMAND(endxmlonly)
|
||||
152
thirdparty/clang/include/clang-c/CXCompilationDatabase.h
vendored
Normal file
152
thirdparty/clang/include/clang-c/CXCompilationDatabase.h
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
/*===-- clang-c/CXCompilationDatabase.h - Compilation database ---*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides a public inferface to use CompilationDatabase without *|
|
||||
|* the full Clang C++ API. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef CLANG_CXCOMPILATIONDATABASE_H
|
||||
#define CLANG_CXCOMPILATIONDATABASE_H
|
||||
|
||||
#include "clang-c/Platform.h"
|
||||
#include "clang-c/CXString.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup COMPILATIONDB CompilationDatabase functions
|
||||
* \ingroup CINDEX
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* A compilation database holds all information used to compile files in a
|
||||
* project. For each file in the database, it can be queried for the working
|
||||
* directory or the command line used for the compiler invocation.
|
||||
*
|
||||
* Must be freed by \c clang_CompilationDatabase_dispose
|
||||
*/
|
||||
typedef void * CXCompilationDatabase;
|
||||
|
||||
/**
|
||||
* \brief Contains the results of a search in the compilation database
|
||||
*
|
||||
* When searching for the compile command for a file, the compilation db can
|
||||
* return several commands, as the file may have been compiled with
|
||||
* different options in different places of the project. This choice of compile
|
||||
* commands is wrapped in this opaque data structure. It must be freed by
|
||||
* \c clang_CompileCommands_dispose.
|
||||
*/
|
||||
typedef void * CXCompileCommands;
|
||||
|
||||
/**
|
||||
* \brief Represents the command line invocation to compile a specific file.
|
||||
*/
|
||||
typedef void * CXCompileCommand;
|
||||
|
||||
/**
|
||||
* \brief Error codes for Compilation Database
|
||||
*/
|
||||
typedef enum {
|
||||
/*
|
||||
* \brief No error occured
|
||||
*/
|
||||
CXCompilationDatabase_NoError = 0,
|
||||
|
||||
/*
|
||||
* \brief Database can not be loaded
|
||||
*/
|
||||
CXCompilationDatabase_CanNotLoadDatabase = 1
|
||||
|
||||
} CXCompilationDatabase_Error;
|
||||
|
||||
/**
|
||||
* \brief Creates a compilation database from the database found in directory
|
||||
* buildDir. For example, CMake can output a compile_commands.json which can
|
||||
* be used to build the database.
|
||||
*
|
||||
* It must be freed by \c clang_CompilationDatabase_dispose.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompilationDatabase
|
||||
clang_CompilationDatabase_fromDirectory(const char *BuildDir,
|
||||
CXCompilationDatabase_Error *ErrorCode);
|
||||
|
||||
/**
|
||||
* \brief Free the given compilation database
|
||||
*/
|
||||
CINDEX_LINKAGE void
|
||||
clang_CompilationDatabase_dispose(CXCompilationDatabase);
|
||||
|
||||
/**
|
||||
* \brief Find the compile commands used for a file. The compile commands
|
||||
* must be freed by \c clang_CompileCommands_dispose.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommands
|
||||
clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase,
|
||||
const char *CompleteFileName);
|
||||
|
||||
/**
|
||||
* \brief Get all the compile commands in the given compilation database.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommands
|
||||
clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase);
|
||||
|
||||
/**
|
||||
* \brief Free the given CompileCommands
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
|
||||
|
||||
/**
|
||||
* \brief Get the number of CompileCommand we have for a file
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommands_getSize(CXCompileCommands);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th CompileCommand for a file
|
||||
*
|
||||
* Note : 0 <= i < clang_CompileCommands_getSize(CXCompileCommands)
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommand
|
||||
clang_CompileCommands_getCommand(CXCompileCommands, unsigned I);
|
||||
|
||||
/**
|
||||
* \brief Get the working directory where the CompileCommand was executed from
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getDirectory(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the number of arguments in the compiler invocation.
|
||||
*
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommand_getNumArgs(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th argument value in the compiler invocations
|
||||
*
|
||||
* Invariant :
|
||||
* - argument 0 is the compiler executable
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getArg(CXCompileCommand, unsigned I);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
61
thirdparty/clang/include/clang-c/CXString.h
vendored
Normal file
61
thirdparty/clang/include/clang-c/CXString.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*===-- clang-c/CXString.h - C Index strings --------------------*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides the interface to C Index strings. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef CLANG_CXSTRING_H
|
||||
#define CLANG_CXSTRING_H
|
||||
|
||||
#include "clang-c/Platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \defgroup CINDEX_STRING String manipulation routines
|
||||
* \ingroup CINDEX
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief A character string.
|
||||
*
|
||||
* The \c CXString type is used to return strings from the interface when
|
||||
* the ownership of that string might different from one call to the next.
|
||||
* Use \c clang_getCString() to retrieve the string data and, once finished
|
||||
* with the string data, call \c clang_disposeString() to free the string.
|
||||
*/
|
||||
typedef struct {
|
||||
const void *data;
|
||||
unsigned private_flags;
|
||||
} CXString;
|
||||
|
||||
/**
|
||||
* \brief Retrieve the character data associated with the given string.
|
||||
*/
|
||||
CINDEX_LINKAGE const char *clang_getCString(CXString string);
|
||||
|
||||
/**
|
||||
* \brief Free the given string,
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_disposeString(CXString string);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
5784
thirdparty/clang/include/clang-c/Index.h
vendored
Normal file
5784
thirdparty/clang/include/clang-c/Index.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
45
thirdparty/clang/include/clang-c/Platform.h
vendored
Normal file
45
thirdparty/clang/include/clang-c/Platform.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*===-- clang-c/Platform.h - C Index platform decls -------------*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides platform specific macros (dllimport, deprecated, ...) *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef CLANG_C_PLATFORM_H
|
||||
#define CLANG_C_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* MSVC DLL import/export. */
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _CINDEX_LIB_
|
||||
#define CINDEX_LINKAGE __declspec(dllexport)
|
||||
#else
|
||||
#define CINDEX_LINKAGE __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define CINDEX_LINKAGE
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CINDEX_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#define CINDEX_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#define CINDEX_DEPRECATED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
123
thirdparty/clang/include/clang/ARCMigrate/ARCMT.h
vendored
Normal file
123
thirdparty/clang/include/clang/ARCMigrate/ARCMT.h
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_H
|
||||
#define LLVM_CLANG_ARCMIGRATE_ARCMT_H
|
||||
|
||||
#include "clang/ARCMigrate/FileRemapper.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class DiagnosticConsumer;
|
||||
|
||||
namespace arcmt {
|
||||
class MigrationPass;
|
||||
|
||||
/// \brief Creates an AST with the provided CompilerInvocation but with these
|
||||
/// changes:
|
||||
/// -if a PCH/PTH is set, the original header is used instead
|
||||
/// -Automatic Reference Counting mode is enabled
|
||||
///
|
||||
/// It then checks the AST and produces errors/warning for ARC migration issues
|
||||
/// that the user needs to handle manually.
|
||||
///
|
||||
/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
|
||||
/// even if the migrator can fix them, but the function will still return false
|
||||
/// if all ARC errors can be fixed.
|
||||
///
|
||||
/// \param plistOut if non-empty, it is the file path to store the plist with
|
||||
/// the pre-migration ARC diagnostics.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool checkForManualIssues(CompilerInvocation &CI,
|
||||
const FrontendInputFile &Input,
|
||||
DiagnosticConsumer *DiagClient,
|
||||
bool emitPremigrationARCErrors = false,
|
||||
StringRef plistOut = StringRef());
|
||||
|
||||
/// \brief Works similar to checkForManualIssues but instead of checking, it
|
||||
/// applies automatic modifications to source files to conform to ARC.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool applyTransformations(CompilerInvocation &origCI,
|
||||
const FrontendInputFile &Input,
|
||||
DiagnosticConsumer *DiagClient);
|
||||
|
||||
/// \brief Applies automatic modifications and produces temporary files
|
||||
/// and metadata into the \p outputDir path.
|
||||
///
|
||||
/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
|
||||
/// even if the migrator can fix them, but the function will still return false
|
||||
/// if all ARC errors can be fixed.
|
||||
///
|
||||
/// \param plistOut if non-empty, it is the file path to store the plist with
|
||||
/// the pre-migration ARC diagnostics.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool migrateWithTemporaryFiles(CompilerInvocation &origCI,
|
||||
const FrontendInputFile &Input,
|
||||
DiagnosticConsumer *DiagClient,
|
||||
StringRef outputDir,
|
||||
bool emitPremigrationARCErrors,
|
||||
StringRef plistOut);
|
||||
|
||||
/// \brief Get the set of file remappings from the \p outputDir path that
|
||||
/// migrateWithTemporaryFiles produced.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap,
|
||||
StringRef outputDir,
|
||||
DiagnosticConsumer *DiagClient);
|
||||
|
||||
/// \brief Get the set of file remappings from a list of files with remapping
|
||||
/// info.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool getFileRemappingsFromFileList(
|
||||
std::vector<std::pair<std::string,std::string> > &remap,
|
||||
ArrayRef<StringRef> remapFiles,
|
||||
DiagnosticConsumer *DiagClient);
|
||||
|
||||
typedef void (*TransformFn)(MigrationPass &pass);
|
||||
|
||||
std::vector<TransformFn> getAllTransformations(LangOptions::GCMode OrigGCMode,
|
||||
bool NoFinalizeRemoval);
|
||||
|
||||
class MigrationProcess {
|
||||
CompilerInvocation OrigCI;
|
||||
DiagnosticConsumer *DiagClient;
|
||||
FileRemapper Remapper;
|
||||
|
||||
public:
|
||||
MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient,
|
||||
StringRef outputDir = StringRef());
|
||||
|
||||
class RewriteListener {
|
||||
public:
|
||||
virtual ~RewriteListener();
|
||||
|
||||
virtual void start(ASTContext &Ctx) { }
|
||||
virtual void finish() { }
|
||||
|
||||
virtual void insert(SourceLocation loc, StringRef text) { }
|
||||
virtual void remove(CharSourceRange range) { }
|
||||
};
|
||||
|
||||
bool applyTransform(TransformFn trans, RewriteListener *listener = 0);
|
||||
|
||||
FileRemapper &getRemapper() { return Remapper; }
|
||||
};
|
||||
|
||||
} // end namespace arcmt
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
77
thirdparty/clang/include/clang/ARCMigrate/ARCMTActions.h
vendored
Normal file
77
thirdparty/clang/include/clang/ARCMigrate/ARCMTActions.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
|
||||
#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
|
||||
|
||||
#include "clang/ARCMigrate/FileRemapper.h"
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
|
||||
namespace clang {
|
||||
namespace arcmt {
|
||||
|
||||
class CheckAction : public WrapperFrontendAction {
|
||||
protected:
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
|
||||
public:
|
||||
CheckAction(FrontendAction *WrappedAction);
|
||||
};
|
||||
|
||||
class ModifyAction : public WrapperFrontendAction {
|
||||
protected:
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
|
||||
public:
|
||||
ModifyAction(FrontendAction *WrappedAction);
|
||||
};
|
||||
|
||||
class MigrateSourceAction : public ASTFrontendAction {
|
||||
FileRemapper Remapper;
|
||||
protected:
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
|
||||
StringRef InFile);
|
||||
};
|
||||
|
||||
class MigrateAction : public WrapperFrontendAction {
|
||||
std::string MigrateDir;
|
||||
std::string PlistOut;
|
||||
bool EmitPremigrationARCErros;
|
||||
protected:
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
|
||||
public:
|
||||
MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
|
||||
StringRef plistOut,
|
||||
bool emitPremigrationARCErrors);
|
||||
};
|
||||
|
||||
/// \brief Migrates to modern ObjC syntax.
|
||||
class ObjCMigrateAction : public WrapperFrontendAction {
|
||||
std::string MigrateDir;
|
||||
bool MigrateLiterals;
|
||||
bool MigrateSubscripting;
|
||||
FileRemapper Remapper;
|
||||
CompilerInstance *CompInst;
|
||||
public:
|
||||
ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
|
||||
bool migrateLiterals,
|
||||
bool migrateSubscripting);
|
||||
|
||||
protected:
|
||||
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile);
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
80
thirdparty/clang/include/clang/ARCMigrate/FileRemapper.h
vendored
Normal file
80
thirdparty/clang/include/clang/ARCMigrate/FileRemapper.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
//===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
|
||||
#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
class FileManager;
|
||||
class FileEntry;
|
||||
class DiagnosticsEngine;
|
||||
class PreprocessorOptions;
|
||||
|
||||
namespace arcmt {
|
||||
|
||||
class FileRemapper {
|
||||
// FIXME: Reuse the same FileManager for multiple ASTContexts.
|
||||
OwningPtr<FileManager> FileMgr;
|
||||
|
||||
typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
|
||||
typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
|
||||
MappingsTy FromToMappings;
|
||||
|
||||
llvm::DenseMap<const FileEntry *, const FileEntry *> ToFromMappings;
|
||||
|
||||
public:
|
||||
FileRemapper();
|
||||
~FileRemapper();
|
||||
|
||||
bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag,
|
||||
bool ignoreIfFilesChanged);
|
||||
bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
|
||||
bool ignoreIfFilesChanged);
|
||||
bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag);
|
||||
bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag);
|
||||
|
||||
bool overwriteOriginal(DiagnosticsEngine &Diag,
|
||||
StringRef outputDir = StringRef());
|
||||
|
||||
void remap(StringRef filePath, llvm::MemoryBuffer *memBuf);
|
||||
void remap(StringRef filePath, StringRef newPath);
|
||||
|
||||
void applyMappings(PreprocessorOptions &PPOpts) const;
|
||||
|
||||
void transferMappingsAndClear(PreprocessorOptions &PPOpts);
|
||||
|
||||
void clear(StringRef outputDir = StringRef());
|
||||
|
||||
private:
|
||||
void remap(const FileEntry *file, llvm::MemoryBuffer *memBuf);
|
||||
void remap(const FileEntry *file, const FileEntry *newfile);
|
||||
|
||||
const FileEntry *getOriginalFile(StringRef filePath);
|
||||
void resetTarget(Target &targ);
|
||||
|
||||
bool report(const Twine &err, DiagnosticsEngine &Diag);
|
||||
|
||||
std::string getRemapInfoFile(StringRef outputDir);
|
||||
};
|
||||
|
||||
} // end namespace arcmt
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
446
thirdparty/clang/include/clang/AST/APValue.h
vendored
Normal file
446
thirdparty/clang/include/clang/AST/APValue.h
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the APValue class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_APVALUE_H
|
||||
#define LLVM_CLANG_AST_APVALUE_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
|
||||
namespace clang {
|
||||
class AddrLabelExpr;
|
||||
class ASTContext;
|
||||
class CharUnits;
|
||||
class DiagnosticBuilder;
|
||||
class Expr;
|
||||
class FieldDecl;
|
||||
class Decl;
|
||||
class ValueDecl;
|
||||
class CXXRecordDecl;
|
||||
class QualType;
|
||||
|
||||
/// APValue - This class implements a discriminated union of [uninitialized]
|
||||
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
|
||||
/// [Vector: N * APValue], [Array: N * APValue]
|
||||
class APValue {
|
||||
typedef llvm::APSInt APSInt;
|
||||
typedef llvm::APFloat APFloat;
|
||||
public:
|
||||
enum ValueKind {
|
||||
Uninitialized,
|
||||
Int,
|
||||
Float,
|
||||
ComplexInt,
|
||||
ComplexFloat,
|
||||
LValue,
|
||||
Vector,
|
||||
Array,
|
||||
Struct,
|
||||
Union,
|
||||
MemberPointer,
|
||||
AddrLabelDiff
|
||||
};
|
||||
typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
|
||||
typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
|
||||
union LValuePathEntry {
|
||||
/// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
|
||||
/// in the path. An opaque value of type BaseOrMemberType.
|
||||
void *BaseOrMember;
|
||||
/// ArrayIndex - The array index of the next item in the path.
|
||||
uint64_t ArrayIndex;
|
||||
};
|
||||
struct NoLValuePath {};
|
||||
struct UninitArray {};
|
||||
struct UninitStruct {};
|
||||
private:
|
||||
ValueKind Kind;
|
||||
|
||||
struct ComplexAPSInt {
|
||||
APSInt Real, Imag;
|
||||
ComplexAPSInt() : Real(1), Imag(1) {}
|
||||
};
|
||||
struct ComplexAPFloat {
|
||||
APFloat Real, Imag;
|
||||
ComplexAPFloat() : Real(0.0), Imag(0.0) {}
|
||||
};
|
||||
struct LV;
|
||||
struct Vec {
|
||||
APValue *Elts;
|
||||
unsigned NumElts;
|
||||
Vec() : Elts(0), NumElts(0) {}
|
||||
~Vec() { delete[] Elts; }
|
||||
};
|
||||
struct Arr {
|
||||
APValue *Elts;
|
||||
unsigned NumElts, ArrSize;
|
||||
Arr(unsigned NumElts, unsigned ArrSize);
|
||||
~Arr();
|
||||
};
|
||||
struct StructData {
|
||||
APValue *Elts;
|
||||
unsigned NumBases;
|
||||
unsigned NumFields;
|
||||
StructData(unsigned NumBases, unsigned NumFields);
|
||||
~StructData();
|
||||
};
|
||||
struct UnionData {
|
||||
const FieldDecl *Field;
|
||||
APValue *Value;
|
||||
UnionData();
|
||||
~UnionData();
|
||||
};
|
||||
struct AddrLabelDiffData {
|
||||
const AddrLabelExpr* LHSExpr;
|
||||
const AddrLabelExpr* RHSExpr;
|
||||
};
|
||||
struct MemberPointerData;
|
||||
|
||||
enum {
|
||||
MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
|
||||
sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
|
||||
};
|
||||
|
||||
union {
|
||||
void *Aligner;
|
||||
char Data[MaxSize];
|
||||
};
|
||||
|
||||
public:
|
||||
APValue() : Kind(Uninitialized) {}
|
||||
explicit APValue(const APSInt &I) : Kind(Uninitialized) {
|
||||
MakeInt(); setInt(I);
|
||||
}
|
||||
explicit APValue(const APFloat &F) : Kind(Uninitialized) {
|
||||
MakeFloat(); setFloat(F);
|
||||
}
|
||||
explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
|
||||
MakeVector(); setVector(E, N);
|
||||
}
|
||||
APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
|
||||
MakeComplexInt(); setComplexInt(R, I);
|
||||
}
|
||||
APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
|
||||
MakeComplexFloat(); setComplexFloat(R, I);
|
||||
}
|
||||
APValue(const APValue &RHS);
|
||||
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
|
||||
: Kind(Uninitialized) {
|
||||
MakeLValue(); setLValue(B, O, N, CallIndex);
|
||||
}
|
||||
APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
|
||||
bool OnePastTheEnd, unsigned CallIndex)
|
||||
: Kind(Uninitialized) {
|
||||
MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
|
||||
}
|
||||
APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
|
||||
MakeArray(InitElts, Size);
|
||||
}
|
||||
APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
|
||||
MakeStruct(B, M);
|
||||
}
|
||||
explicit APValue(const FieldDecl *D, const APValue &V = APValue())
|
||||
: Kind(Uninitialized) {
|
||||
MakeUnion(); setUnion(D, V);
|
||||
}
|
||||
APValue(const ValueDecl *Member, bool IsDerivedMember,
|
||||
ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
|
||||
MakeMemberPointer(Member, IsDerivedMember, Path);
|
||||
}
|
||||
APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
|
||||
: Kind(Uninitialized) {
|
||||
MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
|
||||
}
|
||||
|
||||
~APValue() {
|
||||
MakeUninit();
|
||||
}
|
||||
|
||||
/// \brief Swaps the contents of this and the given APValue.
|
||||
void swap(APValue &RHS);
|
||||
|
||||
ValueKind getKind() const { return Kind; }
|
||||
bool isUninit() const { return Kind == Uninitialized; }
|
||||
bool isInt() const { return Kind == Int; }
|
||||
bool isFloat() const { return Kind == Float; }
|
||||
bool isComplexInt() const { return Kind == ComplexInt; }
|
||||
bool isComplexFloat() const { return Kind == ComplexFloat; }
|
||||
bool isLValue() const { return Kind == LValue; }
|
||||
bool isVector() const { return Kind == Vector; }
|
||||
bool isArray() const { return Kind == Array; }
|
||||
bool isStruct() const { return Kind == Struct; }
|
||||
bool isUnion() const { return Kind == Union; }
|
||||
bool isMemberPointer() const { return Kind == MemberPointer; }
|
||||
bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
|
||||
|
||||
void dump() const;
|
||||
void dump(raw_ostream &OS) const;
|
||||
|
||||
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
|
||||
std::string getAsString(ASTContext &Ctx, QualType Ty) const;
|
||||
|
||||
APSInt &getInt() {
|
||||
assert(isInt() && "Invalid accessor");
|
||||
return *(APSInt*)(char*)Data;
|
||||
}
|
||||
const APSInt &getInt() const {
|
||||
return const_cast<APValue*>(this)->getInt();
|
||||
}
|
||||
|
||||
APFloat &getFloat() {
|
||||
assert(isFloat() && "Invalid accessor");
|
||||
return *(APFloat*)(char*)Data;
|
||||
}
|
||||
const APFloat &getFloat() const {
|
||||
return const_cast<APValue*>(this)->getFloat();
|
||||
}
|
||||
|
||||
APSInt &getComplexIntReal() {
|
||||
assert(isComplexInt() && "Invalid accessor");
|
||||
return ((ComplexAPSInt*)(char*)Data)->Real;
|
||||
}
|
||||
const APSInt &getComplexIntReal() const {
|
||||
return const_cast<APValue*>(this)->getComplexIntReal();
|
||||
}
|
||||
|
||||
APSInt &getComplexIntImag() {
|
||||
assert(isComplexInt() && "Invalid accessor");
|
||||
return ((ComplexAPSInt*)(char*)Data)->Imag;
|
||||
}
|
||||
const APSInt &getComplexIntImag() const {
|
||||
return const_cast<APValue*>(this)->getComplexIntImag();
|
||||
}
|
||||
|
||||
APFloat &getComplexFloatReal() {
|
||||
assert(isComplexFloat() && "Invalid accessor");
|
||||
return ((ComplexAPFloat*)(char*)Data)->Real;
|
||||
}
|
||||
const APFloat &getComplexFloatReal() const {
|
||||
return const_cast<APValue*>(this)->getComplexFloatReal();
|
||||
}
|
||||
|
||||
APFloat &getComplexFloatImag() {
|
||||
assert(isComplexFloat() && "Invalid accessor");
|
||||
return ((ComplexAPFloat*)(char*)Data)->Imag;
|
||||
}
|
||||
const APFloat &getComplexFloatImag() const {
|
||||
return const_cast<APValue*>(this)->getComplexFloatImag();
|
||||
}
|
||||
|
||||
const LValueBase getLValueBase() const;
|
||||
CharUnits &getLValueOffset();
|
||||
const CharUnits &getLValueOffset() const {
|
||||
return const_cast<APValue*>(this)->getLValueOffset();
|
||||
}
|
||||
bool isLValueOnePastTheEnd() const;
|
||||
bool hasLValuePath() const;
|
||||
ArrayRef<LValuePathEntry> getLValuePath() const;
|
||||
unsigned getLValueCallIndex() const;
|
||||
|
||||
APValue &getVectorElt(unsigned I) {
|
||||
assert(isVector() && "Invalid accessor");
|
||||
assert(I < getVectorLength() && "Index out of range");
|
||||
return ((Vec*)(char*)Data)->Elts[I];
|
||||
}
|
||||
const APValue &getVectorElt(unsigned I) const {
|
||||
return const_cast<APValue*>(this)->getVectorElt(I);
|
||||
}
|
||||
unsigned getVectorLength() const {
|
||||
assert(isVector() && "Invalid accessor");
|
||||
return ((const Vec*)(const void *)Data)->NumElts;
|
||||
}
|
||||
|
||||
APValue &getArrayInitializedElt(unsigned I) {
|
||||
assert(isArray() && "Invalid accessor");
|
||||
assert(I < getArrayInitializedElts() && "Index out of range");
|
||||
return ((Arr*)(char*)Data)->Elts[I];
|
||||
}
|
||||
const APValue &getArrayInitializedElt(unsigned I) const {
|
||||
return const_cast<APValue*>(this)->getArrayInitializedElt(I);
|
||||
}
|
||||
bool hasArrayFiller() const {
|
||||
return getArrayInitializedElts() != getArraySize();
|
||||
}
|
||||
APValue &getArrayFiller() {
|
||||
assert(isArray() && "Invalid accessor");
|
||||
assert(hasArrayFiller() && "No array filler");
|
||||
return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()];
|
||||
}
|
||||
const APValue &getArrayFiller() const {
|
||||
return const_cast<APValue*>(this)->getArrayFiller();
|
||||
}
|
||||
unsigned getArrayInitializedElts() const {
|
||||
assert(isArray() && "Invalid accessor");
|
||||
return ((const Arr*)(const void *)Data)->NumElts;
|
||||
}
|
||||
unsigned getArraySize() const {
|
||||
assert(isArray() && "Invalid accessor");
|
||||
return ((const Arr*)(const void *)Data)->ArrSize;
|
||||
}
|
||||
|
||||
unsigned getStructNumBases() const {
|
||||
assert(isStruct() && "Invalid accessor");
|
||||
return ((const StructData*)(const char*)Data)->NumBases;
|
||||
}
|
||||
unsigned getStructNumFields() const {
|
||||
assert(isStruct() && "Invalid accessor");
|
||||
return ((const StructData*)(const char*)Data)->NumFields;
|
||||
}
|
||||
APValue &getStructBase(unsigned i) {
|
||||
assert(isStruct() && "Invalid accessor");
|
||||
return ((StructData*)(char*)Data)->Elts[i];
|
||||
}
|
||||
APValue &getStructField(unsigned i) {
|
||||
assert(isStruct() && "Invalid accessor");
|
||||
return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i];
|
||||
}
|
||||
const APValue &getStructBase(unsigned i) const {
|
||||
return const_cast<APValue*>(this)->getStructBase(i);
|
||||
}
|
||||
const APValue &getStructField(unsigned i) const {
|
||||
return const_cast<APValue*>(this)->getStructField(i);
|
||||
}
|
||||
|
||||
const FieldDecl *getUnionField() const {
|
||||
assert(isUnion() && "Invalid accessor");
|
||||
return ((const UnionData*)(const char*)Data)->Field;
|
||||
}
|
||||
APValue &getUnionValue() {
|
||||
assert(isUnion() && "Invalid accessor");
|
||||
return *((UnionData*)(char*)Data)->Value;
|
||||
}
|
||||
const APValue &getUnionValue() const {
|
||||
return const_cast<APValue*>(this)->getUnionValue();
|
||||
}
|
||||
|
||||
const ValueDecl *getMemberPointerDecl() const;
|
||||
bool isMemberPointerToDerivedMember() const;
|
||||
ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
|
||||
|
||||
const AddrLabelExpr* getAddrLabelDiffLHS() const {
|
||||
assert(isAddrLabelDiff() && "Invalid accessor");
|
||||
return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr;
|
||||
}
|
||||
const AddrLabelExpr* getAddrLabelDiffRHS() const {
|
||||
assert(isAddrLabelDiff() && "Invalid accessor");
|
||||
return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr;
|
||||
}
|
||||
|
||||
void setInt(const APSInt &I) {
|
||||
assert(isInt() && "Invalid accessor");
|
||||
*(APSInt*)(char*)Data = I;
|
||||
}
|
||||
void setFloat(const APFloat &F) {
|
||||
assert(isFloat() && "Invalid accessor");
|
||||
*(APFloat*)(char*)Data = F;
|
||||
}
|
||||
void setVector(const APValue *E, unsigned N) {
|
||||
assert(isVector() && "Invalid accessor");
|
||||
((Vec*)(char*)Data)->Elts = new APValue[N];
|
||||
((Vec*)(char*)Data)->NumElts = N;
|
||||
for (unsigned i = 0; i != N; ++i)
|
||||
((Vec*)(char*)Data)->Elts[i] = E[i];
|
||||
}
|
||||
void setComplexInt(const APSInt &R, const APSInt &I) {
|
||||
assert(R.getBitWidth() == I.getBitWidth() &&
|
||||
"Invalid complex int (type mismatch).");
|
||||
assert(isComplexInt() && "Invalid accessor");
|
||||
((ComplexAPSInt*)(char*)Data)->Real = R;
|
||||
((ComplexAPSInt*)(char*)Data)->Imag = I;
|
||||
}
|
||||
void setComplexFloat(const APFloat &R, const APFloat &I) {
|
||||
assert(&R.getSemantics() == &I.getSemantics() &&
|
||||
"Invalid complex float (type mismatch).");
|
||||
assert(isComplexFloat() && "Invalid accessor");
|
||||
((ComplexAPFloat*)(char*)Data)->Real = R;
|
||||
((ComplexAPFloat*)(char*)Data)->Imag = I;
|
||||
}
|
||||
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
|
||||
unsigned CallIndex);
|
||||
void setLValue(LValueBase B, const CharUnits &O,
|
||||
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
|
||||
unsigned CallIndex);
|
||||
void setUnion(const FieldDecl *Field, const APValue &Value) {
|
||||
assert(isUnion() && "Invalid accessor");
|
||||
((UnionData*)(char*)Data)->Field = Field;
|
||||
*((UnionData*)(char*)Data)->Value = Value;
|
||||
}
|
||||
void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
|
||||
const AddrLabelExpr* RHSExpr) {
|
||||
((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr;
|
||||
((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
|
||||
}
|
||||
|
||||
/// Assign by swapping from a copy of the RHS.
|
||||
APValue &operator=(APValue RHS) {
|
||||
swap(RHS);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void DestroyDataAndMakeUninit();
|
||||
void MakeUninit() {
|
||||
if (Kind != Uninitialized)
|
||||
DestroyDataAndMakeUninit();
|
||||
}
|
||||
void MakeInt() {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)Data) APSInt(1);
|
||||
Kind = Int;
|
||||
}
|
||||
void MakeFloat() {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)(char*)Data) APFloat(0.0);
|
||||
Kind = Float;
|
||||
}
|
||||
void MakeVector() {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)(char*)Data) Vec();
|
||||
Kind = Vector;
|
||||
}
|
||||
void MakeComplexInt() {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)(char*)Data) ComplexAPSInt();
|
||||
Kind = ComplexInt;
|
||||
}
|
||||
void MakeComplexFloat() {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)(char*)Data) ComplexAPFloat();
|
||||
Kind = ComplexFloat;
|
||||
}
|
||||
void MakeLValue();
|
||||
void MakeArray(unsigned InitElts, unsigned Size);
|
||||
void MakeStruct(unsigned B, unsigned M) {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)(char*)Data) StructData(B, M);
|
||||
Kind = Struct;
|
||||
}
|
||||
void MakeUnion() {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)(char*)Data) UnionData();
|
||||
Kind = Union;
|
||||
}
|
||||
void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
|
||||
ArrayRef<const CXXRecordDecl*> Path);
|
||||
void MakeAddrLabelDiff() {
|
||||
assert(isUninit() && "Bad state change");
|
||||
new ((void*)(char*)Data) AddrLabelDiffData();
|
||||
Kind = AddrLabelDiff;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang.
|
||||
|
||||
#endif
|
||||
28
thirdparty/clang/include/clang/AST/AST.h
vendored
Normal file
28
thirdparty/clang/include/clang/AST/AST.h
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
//===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the interface to the AST classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_AST_H
|
||||
#define LLVM_CLANG_AST_AST_H
|
||||
|
||||
// This header exports all AST interfaces.
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "clang/AST/Type.h"
|
||||
|
||||
#endif
|
||||
140
thirdparty/clang/include/clang/AST/ASTConsumer.h
vendored
Normal file
140
thirdparty/clang/include/clang/AST/ASTConsumer.h
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ASTConsumer class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
|
||||
#define LLVM_CLANG_AST_ASTCONSUMER_H
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CXXRecordDecl;
|
||||
class Decl;
|
||||
class DeclGroupRef;
|
||||
class HandleTagDeclDefinition;
|
||||
class ASTMutationListener;
|
||||
class ASTDeserializationListener; // layering violation because void* is ugly
|
||||
class SemaConsumer; // layering violation required for safe SemaConsumer
|
||||
class TagDecl;
|
||||
class VarDecl;
|
||||
class FunctionDecl;
|
||||
class ImportDecl;
|
||||
|
||||
/// ASTConsumer - This is an abstract interface that should be implemented by
|
||||
/// clients that read ASTs. This abstraction layer allows the client to be
|
||||
/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
|
||||
class ASTConsumer {
|
||||
/// \brief Whether this AST consumer also requires information about
|
||||
/// semantic analysis.
|
||||
bool SemaConsumer;
|
||||
|
||||
friend class SemaConsumer;
|
||||
|
||||
public:
|
||||
ASTConsumer() : SemaConsumer(false) { }
|
||||
|
||||
virtual ~ASTConsumer() {}
|
||||
|
||||
/// Initialize - This is called to initialize the consumer, providing the
|
||||
/// ASTContext.
|
||||
virtual void Initialize(ASTContext &Context) {}
|
||||
|
||||
/// HandleTopLevelDecl - Handle the specified top-level declaration. This is
|
||||
/// called by the parser to process every top-level Decl*. Note that D can be
|
||||
/// the head of a chain of Decls (e.g. for `int a, b` the chain will have two
|
||||
/// elements). Use Decl::getNextDeclarator() to walk the chain.
|
||||
///
|
||||
/// \returns true to continue parsing, or false to abort parsing.
|
||||
virtual bool HandleTopLevelDecl(DeclGroupRef D);
|
||||
|
||||
/// HandleInterestingDecl - Handle the specified interesting declaration. This
|
||||
/// is called by the AST reader when deserializing things that might interest
|
||||
/// the consumer. The default implementation forwards to HandleTopLevelDecl.
|
||||
virtual void HandleInterestingDecl(DeclGroupRef D);
|
||||
|
||||
/// HandleTranslationUnit - This method is called when the ASTs for entire
|
||||
/// translation unit have been parsed.
|
||||
virtual void HandleTranslationUnit(ASTContext &Ctx) {}
|
||||
|
||||
/// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
|
||||
/// (e.g. struct, union, enum, class) is completed. This allows the client to
|
||||
/// hack on the type, which can occur at any point in the file (because these
|
||||
/// can be defined in declspecs).
|
||||
virtual void HandleTagDeclDefinition(TagDecl *D) {}
|
||||
|
||||
/// \brief Invoked when a function is implicitly instantiated.
|
||||
/// Note that at this point point it does not have a body, its body is
|
||||
/// instantiated at the end of the translation unit and passed to
|
||||
/// HandleTopLevelDecl.
|
||||
virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
|
||||
|
||||
/// \brief Handle the specified top-level declaration that occurred inside
|
||||
/// and ObjC container.
|
||||
/// The default implementation ignored them.
|
||||
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
|
||||
|
||||
/// \brief Handle an ImportDecl that was implicitly created due to an
|
||||
/// inclusion directive.
|
||||
/// The default implementation passes it to HandleTopLevelDecl.
|
||||
virtual void HandleImplicitImportDecl(ImportDecl *D);
|
||||
|
||||
/// CompleteTentativeDefinition - Callback invoked at the end of a translation
|
||||
/// unit to notify the consumer that the given tentative definition should be
|
||||
/// completed.
|
||||
///
|
||||
/// The variable declaration itself will be a tentative
|
||||
/// definition. If it had an incomplete array type, its type will
|
||||
/// have already been changed to an array of size 1. However, the
|
||||
/// declaration remains a tentative definition and has not been
|
||||
/// modified by the introduction of an implicit zero initializer.
|
||||
virtual void CompleteTentativeDefinition(VarDecl *D) {}
|
||||
|
||||
/// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
|
||||
// variable has been instantiated.
|
||||
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
|
||||
|
||||
/// \brief Callback involved at the end of a translation unit to
|
||||
/// notify the consumer that a vtable for the given C++ class is
|
||||
/// required.
|
||||
///
|
||||
/// \param RD The class whose vtable was used.
|
||||
///
|
||||
/// \param DefinitionRequired Whether a definition of this vtable is
|
||||
/// required in this translation unit; otherwise, it is only needed if
|
||||
/// it was actually used.
|
||||
virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
|
||||
|
||||
/// \brief If the consumer is interested in entities getting modified after
|
||||
/// their initial creation, it should return a pointer to
|
||||
/// an ASTMutationListener here.
|
||||
virtual ASTMutationListener *GetASTMutationListener() { return 0; }
|
||||
|
||||
/// \brief If the consumer is interested in entities being deserialized from
|
||||
/// AST files, it should return a pointer to a ASTDeserializationListener here
|
||||
virtual ASTDeserializationListener *GetASTDeserializationListener() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// PrintStats - If desired, print any statistics.
|
||||
virtual void PrintStats() {}
|
||||
|
||||
/// \brief This callback is called for each function if the Parser was
|
||||
/// initialized with \c SkipFunctionBodies set to \c true.
|
||||
///
|
||||
/// \return \c true if the function's body should be skipped. The function
|
||||
/// body may be parsed anyway if it is needed (for instance, if it contains
|
||||
/// the code completion point or is constexpr).
|
||||
virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
|
||||
};
|
||||
|
||||
} // end namespace clang.
|
||||
|
||||
#endif
|
||||
2363
thirdparty/clang/include/clang/AST/ASTContext.h
vendored
Normal file
2363
thirdparty/clang/include/clang/AST/ASTContext.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
50
thirdparty/clang/include/clang/AST/ASTDiagnostic.h
vendored
Normal file
50
thirdparty/clang/include/clang/AST/ASTDiagnostic.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_DIAGNOSTICAST_H
|
||||
#define LLVM_CLANG_DIAGNOSTICAST_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
|
||||
SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
|
||||
#define ASTSTART
|
||||
#include "clang/Basic/DiagnosticASTKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_AST_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
|
||||
/// \brief DiagnosticsEngine argument formatting function for diagnostics that
|
||||
/// involve AST nodes.
|
||||
///
|
||||
/// This function formats diagnostic arguments for various AST nodes,
|
||||
/// including types, declaration names, nested name specifiers, and
|
||||
/// declaration contexts, into strings that can be printed as part of
|
||||
/// diagnostics. It is meant to be used as the argument to
|
||||
/// \c DiagnosticsEngine::SetArgToStringFn(), where the cookie is an \c
|
||||
/// ASTContext pointer.
|
||||
void FormatASTNodeDiagnosticArgument(
|
||||
DiagnosticsEngine::ArgumentKind Kind,
|
||||
intptr_t Val,
|
||||
const char *Modifier,
|
||||
unsigned ModLen,
|
||||
const char *Argument,
|
||||
unsigned ArgLen,
|
||||
const DiagnosticsEngine::ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
SmallVectorImpl<char> &Output,
|
||||
void *Cookie,
|
||||
ArrayRef<intptr_t> QualTypeVals);
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
282
thirdparty/clang/include/clang/AST/ASTImporter.h
vendored
Normal file
282
thirdparty/clang/include/clang/AST/ASTImporter.h
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ASTImporter class which imports AST nodes from one
|
||||
// context into another context.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
|
||||
#define LLVM_CLANG_AST_ASTIMPORTER_H
|
||||
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class Decl;
|
||||
class DeclContext;
|
||||
class DiagnosticsEngine;
|
||||
class Expr;
|
||||
class FileManager;
|
||||
class IdentifierInfo;
|
||||
class NestedNameSpecifier;
|
||||
class Stmt;
|
||||
class TypeSourceInfo;
|
||||
|
||||
/// \brief Imports selected nodes from one AST context into another context,
|
||||
/// merging AST nodes where appropriate.
|
||||
class ASTImporter {
|
||||
public:
|
||||
typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
|
||||
|
||||
private:
|
||||
/// \brief The contexts we're importing to and from.
|
||||
ASTContext &ToContext, &FromContext;
|
||||
|
||||
/// \brief The file managers we're importing to and from.
|
||||
FileManager &ToFileManager, &FromFileManager;
|
||||
|
||||
/// \brief Whether to perform a minimal import.
|
||||
bool Minimal;
|
||||
|
||||
/// \brief Whether the last diagnostic came from the "from" context.
|
||||
bool LastDiagFromFrom;
|
||||
|
||||
/// \brief Mapping from the already-imported types in the "from" context
|
||||
/// to the corresponding types in the "to" context.
|
||||
llvm::DenseMap<const Type *, const Type *> ImportedTypes;
|
||||
|
||||
/// \brief Mapping from the already-imported declarations in the "from"
|
||||
/// context to the corresponding declarations in the "to" context.
|
||||
llvm::DenseMap<Decl *, Decl *> ImportedDecls;
|
||||
|
||||
/// \brief Mapping from the already-imported statements in the "from"
|
||||
/// context to the corresponding statements in the "to" context.
|
||||
llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
|
||||
|
||||
/// \brief Mapping from the already-imported FileIDs in the "from" source
|
||||
/// manager to the corresponding FileIDs in the "to" source manager.
|
||||
llvm::DenseMap<FileID, FileID> ImportedFileIDs;
|
||||
|
||||
/// \brief Imported, anonymous tag declarations that are missing their
|
||||
/// corresponding typedefs.
|
||||
SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
|
||||
|
||||
/// \brief Declaration (from, to) pairs that are known not to be equivalent
|
||||
/// (which we have already complained about).
|
||||
NonEquivalentDeclSet NonEquivalentDecls;
|
||||
|
||||
public:
|
||||
/// \brief Create a new AST importer.
|
||||
///
|
||||
/// \param ToContext The context we'll be importing into.
|
||||
///
|
||||
/// \param ToFileManager The file manager we'll be importing into.
|
||||
///
|
||||
/// \param FromContext The context we'll be importing from.
|
||||
///
|
||||
/// \param FromFileManager The file manager we'll be importing into.
|
||||
///
|
||||
/// \param MinimalImport If true, the importer will attempt to import
|
||||
/// as little as it can, e.g., by importing declarations as forward
|
||||
/// declarations that can be completed at a later point.
|
||||
ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
|
||||
ASTContext &FromContext, FileManager &FromFileManager,
|
||||
bool MinimalImport);
|
||||
|
||||
virtual ~ASTImporter();
|
||||
|
||||
/// \brief Whether the importer will perform a minimal import, creating
|
||||
/// to-be-completed forward declarations when possible.
|
||||
bool isMinimalImport() const { return Minimal; }
|
||||
|
||||
/// \brief Import the given type from the "from" context into the "to"
|
||||
/// context.
|
||||
///
|
||||
/// \returns the equivalent type in the "to" context, or a NULL type if
|
||||
/// an error occurred.
|
||||
QualType Import(QualType FromT);
|
||||
|
||||
/// \brief Import the given type source information from the
|
||||
/// "from" context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent type source information in the "to"
|
||||
/// context, or NULL if an error occurred.
|
||||
TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
|
||||
|
||||
/// \brief Import the given declaration from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent declaration in the "to" context, or a NULL type
|
||||
/// if an error occurred.
|
||||
Decl *Import(Decl *FromD);
|
||||
|
||||
/// \brief Import the given declaration context from the "from"
|
||||
/// AST context into the "to" AST context.
|
||||
///
|
||||
/// \returns the equivalent declaration context in the "to"
|
||||
/// context, or a NULL type if an error occurred.
|
||||
DeclContext *ImportContext(DeclContext *FromDC);
|
||||
|
||||
/// \brief Import the given expression from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent expression in the "to" context, or NULL if
|
||||
/// an error occurred.
|
||||
Expr *Import(Expr *FromE);
|
||||
|
||||
/// \brief Import the given statement from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent statement in the "to" context, or NULL if
|
||||
/// an error occurred.
|
||||
Stmt *Import(Stmt *FromS);
|
||||
|
||||
/// \brief Import the given nested-name-specifier from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent nested-name-specifier in the "to"
|
||||
/// context, or NULL if an error occurred.
|
||||
NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
|
||||
|
||||
/// \brief Import the given nested-name-specifier from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent nested-name-specifier in the "to"
|
||||
/// context.
|
||||
NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
|
||||
|
||||
/// \brief Import the goven template name from the "from" context into the
|
||||
/// "to" context.
|
||||
TemplateName Import(TemplateName From);
|
||||
|
||||
/// \brief Import the given source location from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent source location in the "to" context, or an
|
||||
/// invalid source location if an error occurred.
|
||||
SourceLocation Import(SourceLocation FromLoc);
|
||||
|
||||
/// \brief Import the given source range from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent source range in the "to" context, or an
|
||||
/// invalid source location if an error occurred.
|
||||
SourceRange Import(SourceRange FromRange);
|
||||
|
||||
/// \brief Import the given declaration name from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent declaration name in the "to" context,
|
||||
/// or an empty declaration name if an error occurred.
|
||||
DeclarationName Import(DeclarationName FromName);
|
||||
|
||||
/// \brief Import the given identifier from the "from" context
|
||||
/// into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent identifier in the "to" context.
|
||||
IdentifierInfo *Import(const IdentifierInfo *FromId);
|
||||
|
||||
/// \brief Import the given Objective-C selector from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent selector in the "to" context.
|
||||
Selector Import(Selector FromSel);
|
||||
|
||||
/// \brief Import the given file ID from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent file ID in the source manager of the "to"
|
||||
/// context.
|
||||
FileID Import(FileID);
|
||||
|
||||
/// \brief Import the definition of the given declaration, including all of
|
||||
/// the declarations it contains.
|
||||
///
|
||||
/// This routine is intended to be used
|
||||
void ImportDefinition(Decl *From);
|
||||
|
||||
/// \brief Cope with a name conflict when importing a declaration into the
|
||||
/// given context.
|
||||
///
|
||||
/// This routine is invoked whenever there is a name conflict while
|
||||
/// importing a declaration. The returned name will become the name of the
|
||||
/// imported declaration. By default, the returned name is the same as the
|
||||
/// original name, leaving the conflict unresolve such that name lookup
|
||||
/// for this name is likely to find an ambiguity later.
|
||||
///
|
||||
/// Subclasses may override this routine to resolve the conflict, e.g., by
|
||||
/// renaming the declaration being imported.
|
||||
///
|
||||
/// \param Name the name of the declaration being imported, which conflicts
|
||||
/// with other declarations.
|
||||
///
|
||||
/// \param DC the declaration context (in the "to" AST context) in which
|
||||
/// the name is being imported.
|
||||
///
|
||||
/// \param IDNS the identifier namespace in which the name will be found.
|
||||
///
|
||||
/// \param Decls the set of declarations with the same name as the
|
||||
/// declaration being imported.
|
||||
///
|
||||
/// \param NumDecls the number of conflicting declarations in \p Decls.
|
||||
///
|
||||
/// \returns the name that the newly-imported declaration should have.
|
||||
virtual DeclarationName HandleNameConflict(DeclarationName Name,
|
||||
DeclContext *DC,
|
||||
unsigned IDNS,
|
||||
NamedDecl **Decls,
|
||||
unsigned NumDecls);
|
||||
|
||||
/// \brief Retrieve the context that AST nodes are being imported into.
|
||||
ASTContext &getToContext() const { return ToContext; }
|
||||
|
||||
/// \brief Retrieve the context that AST nodes are being imported from.
|
||||
ASTContext &getFromContext() const { return FromContext; }
|
||||
|
||||
/// \brief Retrieve the file manager that AST nodes are being imported into.
|
||||
FileManager &getToFileManager() const { return ToFileManager; }
|
||||
|
||||
/// \brief Retrieve the file manager that AST nodes are being imported from.
|
||||
FileManager &getFromFileManager() const { return FromFileManager; }
|
||||
|
||||
/// \brief Report a diagnostic in the "to" context.
|
||||
DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
|
||||
|
||||
/// \brief Report a diagnostic in the "from" context.
|
||||
DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
|
||||
|
||||
/// \brief Return the set of declarations that we know are not equivalent.
|
||||
NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
|
||||
|
||||
/// \brief Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
|
||||
/// Mark the Decl as complete, filling it in as much as possible.
|
||||
///
|
||||
/// \param D A declaration in the "to" context.
|
||||
virtual void CompleteDecl(Decl* D);
|
||||
|
||||
/// \brief Note that we have imported the "from" declaration by mapping it
|
||||
/// to the (potentially-newly-created) "to" declaration.
|
||||
///
|
||||
/// Subclasses can override this function to observe all of the \c From ->
|
||||
/// \c To declaration mappings as they are imported.
|
||||
virtual Decl *Imported(Decl *From, Decl *To);
|
||||
|
||||
/// \brief Determine whether the given types are structurally
|
||||
/// equivalent.
|
||||
bool IsStructurallyEquivalent(QualType From, QualType To,
|
||||
bool Complain = true);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LLVM_CLANG_AST_ASTIMPORTER_H
|
||||
87
thirdparty/clang/include/clang/AST/ASTMutationListener.h
vendored
Normal file
87
thirdparty/clang/include/clang/AST/ASTMutationListener.h
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
//===--- ASTMutationListener.h - AST Mutation Interface --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ASTMutationListener interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
|
||||
#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
|
||||
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
|
||||
namespace clang {
|
||||
class CXXRecordDecl;
|
||||
class ClassTemplateDecl;
|
||||
class ClassTemplateSpecializationDecl;
|
||||
class Decl;
|
||||
class DeclContext;
|
||||
class FunctionDecl;
|
||||
class FunctionTemplateDecl;
|
||||
class ObjCCategoryDecl;
|
||||
class ObjCContainerDecl;
|
||||
class ObjCInterfaceDecl;
|
||||
class ObjCPropertyDecl;
|
||||
class TagDecl;
|
||||
class VarDecl;
|
||||
|
||||
/// \brief An abstract interface that should be implemented by listeners
|
||||
/// that want to be notified when an AST entity gets modified after its
|
||||
/// initial creation.
|
||||
class ASTMutationListener {
|
||||
public:
|
||||
virtual ~ASTMutationListener();
|
||||
|
||||
/// \brief A new TagDecl definition was completed.
|
||||
virtual void CompletedTagDefinition(const TagDecl *D) { }
|
||||
|
||||
/// \brief A new declaration with name has been added to a DeclContext.
|
||||
virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {}
|
||||
|
||||
/// \brief An implicit member was added after the definition was completed.
|
||||
virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {}
|
||||
|
||||
/// \brief A template specialization (or partial one) was added to the
|
||||
/// template declaration.
|
||||
virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
|
||||
const ClassTemplateSpecializationDecl *D) {}
|
||||
|
||||
/// \brief A template specialization (or partial one) was added to the
|
||||
/// template declaration.
|
||||
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
|
||||
const FunctionDecl *D) {}
|
||||
|
||||
/// \brief An implicit member got a definition.
|
||||
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
|
||||
|
||||
/// \brief A static data member was implicitly instantiated.
|
||||
virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
|
||||
|
||||
/// \brief A new objc category class was added for an interface.
|
||||
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
|
||||
const ObjCInterfaceDecl *IFD) {}
|
||||
|
||||
/// \brief A objc class extension redeclared or introduced a property.
|
||||
///
|
||||
/// \param Prop the property in the class extension
|
||||
///
|
||||
/// \param OrigProp the property from the original interface that was declared
|
||||
/// or null if the property was introduced.
|
||||
///
|
||||
/// \param ClassExt the class extension.
|
||||
virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
|
||||
const ObjCPropertyDecl *OrigProp,
|
||||
const ObjCCategoryDecl *ClassExt) {}
|
||||
|
||||
// NOTE: If new methods are added they should also be added to
|
||||
// MultiplexASTMutationListener.
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
211
thirdparty/clang/include/clang/AST/ASTTypeTraits.h
vendored
Normal file
211
thirdparty/clang/include/clang/AST/ASTTypeTraits.h
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Provides a dynamically typed node container that can be used to store
|
||||
// an AST base node at runtime in the same storage in a type safe way.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
|
||||
#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
|
||||
namespace clang {
|
||||
namespace ast_type_traits {
|
||||
|
||||
/// \brief A dynamically typed AST node container.
|
||||
///
|
||||
/// Stores an AST node in a type safe way. This allows writing code that
|
||||
/// works with different kinds of AST nodes, despite the fact that they don't
|
||||
/// have a common base class.
|
||||
///
|
||||
/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
|
||||
/// and \c get<T>() to retrieve the node as type T if the types match.
|
||||
///
|
||||
/// See \c NodeTypeTag for which node base types are currently supported;
|
||||
/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
|
||||
/// the supported base types.
|
||||
class DynTypedNode {
|
||||
public:
|
||||
/// \brief Creates a \c DynTypedNode from \c Node.
|
||||
template <typename T>
|
||||
static DynTypedNode create(const T &Node) {
|
||||
return BaseConverter<T>::create(Node);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the stored node as type \c T.
|
||||
///
|
||||
/// Returns NULL if the stored node does not have a type that is
|
||||
/// convertible to \c T.
|
||||
///
|
||||
/// For types that have identity via their pointer in the AST
|
||||
/// (like \c Stmt and \c Decl) the returned pointer points to the
|
||||
/// referenced AST node.
|
||||
/// For other types (like \c QualType) the value is stored directly
|
||||
/// in the \c DynTypedNode, and the returned pointer points at
|
||||
/// the storage inside DynTypedNode. For those nodes, do not
|
||||
/// use the pointer outside the scope of the DynTypedNode.
|
||||
template <typename T>
|
||||
const T *get() const {
|
||||
return BaseConverter<T>::get(Tag, Storage.buffer);
|
||||
}
|
||||
|
||||
/// \brief Returns a pointer that identifies the stored AST node.
|
||||
///
|
||||
/// Note that this is not supported by all AST nodes. For AST nodes
|
||||
/// that don't have a pointer-defined identity inside the AST, this
|
||||
/// method returns NULL.
|
||||
const void *getMemoizationData() const;
|
||||
|
||||
private:
|
||||
/// \brief Takes care of converting from and to \c T.
|
||||
template <typename T, typename EnablerT = void> struct BaseConverter;
|
||||
|
||||
/// \brief Supported base node types.
|
||||
enum NodeTypeTag {
|
||||
NT_Decl,
|
||||
NT_Stmt,
|
||||
NT_NestedNameSpecifier,
|
||||
NT_NestedNameSpecifierLoc,
|
||||
NT_QualType,
|
||||
NT_Type,
|
||||
NT_TypeLoc
|
||||
} Tag;
|
||||
|
||||
/// \brief Stores the data of the node.
|
||||
///
|
||||
/// Note that we can store \c Decls and \c Stmts by pointer as they are
|
||||
/// guaranteed to be unique pointers pointing to dedicated storage in the
|
||||
/// AST. \c QualTypes on the other hand do not have storage or unique
|
||||
/// pointers and thus need to be stored by value.
|
||||
llvm::AlignedCharArrayUnion<Decl *, Stmt *, NestedNameSpecifier,
|
||||
NestedNameSpecifierLoc, QualType, Type,
|
||||
TypeLoc> Storage;
|
||||
};
|
||||
|
||||
// FIXME: Pull out abstraction for the following.
|
||||
template<typename T> struct DynTypedNode::BaseConverter<T,
|
||||
typename llvm::enable_if<llvm::is_base_of<Decl, T> >::type> {
|
||||
static const T *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_Decl)
|
||||
return dyn_cast<T>(*reinterpret_cast<Decl*const*>(Storage));
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const Decl &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_Decl;
|
||||
new (Result.Storage.buffer) const Decl*(&Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<typename T> struct DynTypedNode::BaseConverter<T,
|
||||
typename llvm::enable_if<llvm::is_base_of<Stmt, T> >::type> {
|
||||
static const T *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_Stmt)
|
||||
return dyn_cast<T>(*reinterpret_cast<Stmt*const*>(Storage));
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const Stmt &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_Stmt;
|
||||
new (Result.Storage.buffer) const Stmt*(&Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<typename T> struct DynTypedNode::BaseConverter<T,
|
||||
typename llvm::enable_if<llvm::is_base_of<Type, T> >::type> {
|
||||
static const T *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_Type)
|
||||
return dyn_cast<T>(*reinterpret_cast<Type*const*>(Storage));
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const Type &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_Type;
|
||||
new (Result.Storage.buffer) const Type*(&Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<> struct DynTypedNode::BaseConverter<NestedNameSpecifier, void> {
|
||||
static const NestedNameSpecifier *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_NestedNameSpecifier)
|
||||
return *reinterpret_cast<NestedNameSpecifier*const*>(Storage);
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const NestedNameSpecifier &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_NestedNameSpecifier;
|
||||
new (Result.Storage.buffer) const NestedNameSpecifier*(&Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<> struct DynTypedNode::BaseConverter<NestedNameSpecifierLoc, void> {
|
||||
static const NestedNameSpecifierLoc *get(NodeTypeTag Tag,
|
||||
const char Storage[]) {
|
||||
if (Tag == NT_NestedNameSpecifierLoc)
|
||||
return reinterpret_cast<const NestedNameSpecifierLoc*>(Storage);
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const NestedNameSpecifierLoc &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_NestedNameSpecifierLoc;
|
||||
new (Result.Storage.buffer) NestedNameSpecifierLoc(Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<> struct DynTypedNode::BaseConverter<QualType, void> {
|
||||
static const QualType *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_QualType)
|
||||
return reinterpret_cast<const QualType*>(Storage);
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const QualType &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_QualType;
|
||||
new (Result.Storage.buffer) QualType(Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<> struct DynTypedNode::BaseConverter<TypeLoc, void> {
|
||||
static const TypeLoc *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_TypeLoc)
|
||||
return reinterpret_cast<const TypeLoc*>(Storage);
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const TypeLoc &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_TypeLoc;
|
||||
new (Result.Storage.buffer) TypeLoc(Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
// The only operation we allow on unsupported types is \c get.
|
||||
// This allows to conveniently use \c DynTypedNode when having an arbitrary
|
||||
// AST node that is not supported, but prevents misuse - a user cannot create
|
||||
// a DynTypedNode from arbitrary types.
|
||||
template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
|
||||
static const T *get(NodeTypeTag Tag, const char Storage[]) { return NULL; }
|
||||
};
|
||||
|
||||
inline const void *DynTypedNode::getMemoizationData() const {
|
||||
switch (Tag) {
|
||||
case NT_Decl: return BaseConverter<Decl>::get(Tag, Storage.buffer);
|
||||
case NT_Stmt: return BaseConverter<Stmt>::get(Tag, Storage.buffer);
|
||||
default: return NULL;
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace ast_type_traits
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
|
||||
85
thirdparty/clang/include/clang/AST/ASTUnresolvedSet.h
vendored
Normal file
85
thirdparty/clang/include/clang/AST/ASTUnresolvedSet.h
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides an UnresolvedSet-like class, whose contents are
|
||||
// allocated using the allocator associated with an ASTContext.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
|
||||
#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
|
||||
|
||||
#include "clang/AST/ASTVector.h"
|
||||
#include "clang/AST/UnresolvedSet.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
|
||||
class ASTUnresolvedSet {
|
||||
typedef ASTVector<DeclAccessPair> DeclsTy;
|
||||
DeclsTy Decls;
|
||||
|
||||
ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
public:
|
||||
ASTUnresolvedSet() {}
|
||||
ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
|
||||
|
||||
typedef UnresolvedSetIterator iterator;
|
||||
typedef UnresolvedSetIterator const_iterator;
|
||||
|
||||
iterator begin() { return iterator(Decls.begin()); }
|
||||
iterator end() { return iterator(Decls.end()); }
|
||||
|
||||
const_iterator begin() const { return const_iterator(Decls.begin()); }
|
||||
const_iterator end() const { return const_iterator(Decls.end()); }
|
||||
|
||||
void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
|
||||
Decls.push_back(DeclAccessPair::make(D, AS), C);
|
||||
}
|
||||
|
||||
/// Replaces the given declaration with the new one, once.
|
||||
///
|
||||
/// \return true if the set changed
|
||||
bool replace(const NamedDecl* Old, NamedDecl *New, AccessSpecifier AS) {
|
||||
for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
|
||||
if (I->getDecl() == Old) {
|
||||
I->set(New, AS);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void erase(unsigned I) {
|
||||
Decls[I] = Decls.back();
|
||||
Decls.pop_back();
|
||||
}
|
||||
|
||||
void clear() { Decls.clear(); }
|
||||
|
||||
bool empty() const { return Decls.empty(); }
|
||||
unsigned size() const { return Decls.size(); }
|
||||
|
||||
void reserve(ASTContext &C, unsigned N) {
|
||||
Decls.reserve(C, N);
|
||||
}
|
||||
|
||||
void append(ASTContext &C, iterator I, iterator E) {
|
||||
Decls.append(C, I.ir, E.ir);
|
||||
}
|
||||
|
||||
DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
|
||||
const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
401
thirdparty/clang/include/clang/AST/ASTVector.h
vendored
Normal file
401
thirdparty/clang/include/clang/AST/ASTVector.h
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
//===- ASTVector.h - Vector that uses ASTContext for allocation --*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides ASTVector, a vector ADT whose contents are
|
||||
// allocated using the allocator associated with an ASTContext..
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
|
||||
// We can refactor this core logic into something common.
|
||||
|
||||
#ifndef LLVM_CLANG_AST_VECTOR
|
||||
#define LLVM_CLANG_AST_VECTOR
|
||||
|
||||
#include "clang/AST/AttrIterator.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
namespace std {
|
||||
#if _MSC_VER <= 1310
|
||||
// Work around flawed VC++ implementation of std::uninitialized_copy. Define
|
||||
// additional overloads so that elements with pointer types are recognized as
|
||||
// scalars and not objects, causing bizarre type conversion errors.
|
||||
template<class T1, class T2>
|
||||
inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
|
||||
_Scalar_ptr_iterator_tag _Cat;
|
||||
return _Cat;
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
|
||||
_Scalar_ptr_iterator_tag _Cat;
|
||||
return _Cat;
|
||||
}
|
||||
#else
|
||||
// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
|
||||
// is that the above hack won't work if it wasn't fixed.
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
|
||||
template<typename T>
|
||||
class ASTVector {
|
||||
T *Begin, *End, *Capacity;
|
||||
|
||||
void setEnd(T *P) { this->End = P; }
|
||||
|
||||
public:
|
||||
// Default ctor - Initialize to empty.
|
||||
ASTVector() : Begin(NULL), End(NULL), Capacity(NULL) { }
|
||||
|
||||
ASTVector(ASTContext &C, unsigned N)
|
||||
: Begin(NULL), End(NULL), Capacity(NULL) {
|
||||
reserve(C, N);
|
||||
}
|
||||
|
||||
~ASTVector() {
|
||||
if (llvm::is_class<T>::value) {
|
||||
// Destroy the constructed elements in the vector.
|
||||
destroy_range(Begin, End);
|
||||
}
|
||||
}
|
||||
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
// forward iterator creation methods.
|
||||
iterator begin() { return Begin; }
|
||||
const_iterator begin() const { return Begin; }
|
||||
iterator end() { return End; }
|
||||
const_iterator end() const { return End; }
|
||||
|
||||
// reverse iterator creation methods.
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
|
||||
|
||||
bool empty() const { return Begin == End; }
|
||||
size_type size() const { return End-Begin; }
|
||||
|
||||
reference operator[](unsigned idx) {
|
||||
assert(Begin + idx < End);
|
||||
return Begin[idx];
|
||||
}
|
||||
const_reference operator[](unsigned idx) const {
|
||||
assert(Begin + idx < End);
|
||||
return Begin[idx];
|
||||
}
|
||||
|
||||
reference front() {
|
||||
return begin()[0];
|
||||
}
|
||||
const_reference front() const {
|
||||
return begin()[0];
|
||||
}
|
||||
|
||||
reference back() {
|
||||
return end()[-1];
|
||||
}
|
||||
const_reference back() const {
|
||||
return end()[-1];
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
--End;
|
||||
End->~T();
|
||||
}
|
||||
|
||||
T pop_back_val() {
|
||||
T Result = back();
|
||||
pop_back();
|
||||
return Result;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if (llvm::is_class<T>::value) {
|
||||
destroy_range(Begin, End);
|
||||
}
|
||||
End = Begin;
|
||||
}
|
||||
|
||||
/// data - Return a pointer to the vector's buffer, even if empty().
|
||||
pointer data() {
|
||||
return pointer(Begin);
|
||||
}
|
||||
|
||||
/// data - Return a pointer to the vector's buffer, even if empty().
|
||||
const_pointer data() const {
|
||||
return const_pointer(Begin);
|
||||
}
|
||||
|
||||
void push_back(const_reference Elt, ASTContext &C) {
|
||||
if (End < Capacity) {
|
||||
Retry:
|
||||
new (End) T(Elt);
|
||||
++End;
|
||||
return;
|
||||
}
|
||||
grow(C);
|
||||
goto Retry;
|
||||
}
|
||||
|
||||
void reserve(ASTContext &C, unsigned N) {
|
||||
if (unsigned(Capacity-Begin) < N)
|
||||
grow(C, N);
|
||||
}
|
||||
|
||||
/// capacity - Return the total number of elements in the currently allocated
|
||||
/// buffer.
|
||||
size_t capacity() const { return Capacity - Begin; }
|
||||
|
||||
/// append - Add the specified range to the end of the SmallVector.
|
||||
///
|
||||
template<typename in_iter>
|
||||
void append(ASTContext &C, in_iter in_start, in_iter in_end) {
|
||||
size_type NumInputs = std::distance(in_start, in_end);
|
||||
|
||||
if (NumInputs == 0)
|
||||
return;
|
||||
|
||||
// Grow allocated space if needed.
|
||||
if (NumInputs > size_type(this->capacity_ptr()-this->end()))
|
||||
this->grow(C, this->size()+NumInputs);
|
||||
|
||||
// Copy the new elements over.
|
||||
// TODO: NEED To compile time dispatch on whether in_iter is a random access
|
||||
// iterator to use the fast uninitialized_copy.
|
||||
std::uninitialized_copy(in_start, in_end, this->end());
|
||||
this->setEnd(this->end() + NumInputs);
|
||||
}
|
||||
|
||||
/// append - Add the specified range to the end of the SmallVector.
|
||||
///
|
||||
void append(ASTContext &C, size_type NumInputs, const T &Elt) {
|
||||
// Grow allocated space if needed.
|
||||
if (NumInputs > size_type(this->capacity_ptr()-this->end()))
|
||||
this->grow(C, this->size()+NumInputs);
|
||||
|
||||
// Copy the new elements over.
|
||||
std::uninitialized_fill_n(this->end(), NumInputs, Elt);
|
||||
this->setEnd(this->end() + NumInputs);
|
||||
}
|
||||
|
||||
/// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
|
||||
/// starting with "Dest", constructing elements into it as needed.
|
||||
template<typename It1, typename It2>
|
||||
static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
|
||||
std::uninitialized_copy(I, E, Dest);
|
||||
}
|
||||
|
||||
iterator insert(ASTContext &C, iterator I, const T &Elt) {
|
||||
if (I == this->end()) { // Important special case for empty vector.
|
||||
push_back(Elt);
|
||||
return this->end()-1;
|
||||
}
|
||||
|
||||
if (this->EndX < this->CapacityX) {
|
||||
Retry:
|
||||
new (this->end()) T(this->back());
|
||||
this->setEnd(this->end()+1);
|
||||
// Push everything else over.
|
||||
std::copy_backward(I, this->end()-1, this->end());
|
||||
*I = Elt;
|
||||
return I;
|
||||
}
|
||||
size_t EltNo = I-this->begin();
|
||||
this->grow(C);
|
||||
I = this->begin()+EltNo;
|
||||
goto Retry;
|
||||
}
|
||||
|
||||
iterator insert(ASTContext &C, iterator I, size_type NumToInsert,
|
||||
const T &Elt) {
|
||||
if (I == this->end()) { // Important special case for empty vector.
|
||||
append(C, NumToInsert, Elt);
|
||||
return this->end()-1;
|
||||
}
|
||||
|
||||
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
|
||||
size_t InsertElt = I - this->begin();
|
||||
|
||||
// Ensure there is enough space.
|
||||
reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
|
||||
|
||||
// Uninvalidate the iterator.
|
||||
I = this->begin()+InsertElt;
|
||||
|
||||
// If there are more elements between the insertion point and the end of the
|
||||
// range than there are being inserted, we can use a simple approach to
|
||||
// insertion. Since we already reserved space, we know that this won't
|
||||
// reallocate the vector.
|
||||
if (size_t(this->end()-I) >= NumToInsert) {
|
||||
T *OldEnd = this->end();
|
||||
append(C, this->end()-NumToInsert, this->end());
|
||||
|
||||
// Copy the existing elements that get replaced.
|
||||
std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
|
||||
|
||||
std::fill_n(I, NumToInsert, Elt);
|
||||
return I;
|
||||
}
|
||||
|
||||
// Otherwise, we're inserting more elements than exist already, and we're
|
||||
// not inserting at the end.
|
||||
|
||||
// Copy over the elements that we're about to overwrite.
|
||||
T *OldEnd = this->end();
|
||||
this->setEnd(this->end() + NumToInsert);
|
||||
size_t NumOverwritten = OldEnd-I;
|
||||
this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
|
||||
|
||||
// Replace the overwritten part.
|
||||
std::fill_n(I, NumOverwritten, Elt);
|
||||
|
||||
// Insert the non-overwritten middle part.
|
||||
std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
|
||||
return I;
|
||||
}
|
||||
|
||||
template<typename ItTy>
|
||||
iterator insert(ASTContext &C, iterator I, ItTy From, ItTy To) {
|
||||
if (I == this->end()) { // Important special case for empty vector.
|
||||
append(C, From, To);
|
||||
return this->end()-1;
|
||||
}
|
||||
|
||||
size_t NumToInsert = std::distance(From, To);
|
||||
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
|
||||
size_t InsertElt = I - this->begin();
|
||||
|
||||
// Ensure there is enough space.
|
||||
reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
|
||||
|
||||
// Uninvalidate the iterator.
|
||||
I = this->begin()+InsertElt;
|
||||
|
||||
// If there are more elements between the insertion point and the end of the
|
||||
// range than there are being inserted, we can use a simple approach to
|
||||
// insertion. Since we already reserved space, we know that this won't
|
||||
// reallocate the vector.
|
||||
if (size_t(this->end()-I) >= NumToInsert) {
|
||||
T *OldEnd = this->end();
|
||||
append(C, this->end()-NumToInsert, this->end());
|
||||
|
||||
// Copy the existing elements that get replaced.
|
||||
std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
|
||||
|
||||
std::copy(From, To, I);
|
||||
return I;
|
||||
}
|
||||
|
||||
// Otherwise, we're inserting more elements than exist already, and we're
|
||||
// not inserting at the end.
|
||||
|
||||
// Copy over the elements that we're about to overwrite.
|
||||
T *OldEnd = this->end();
|
||||
this->setEnd(this->end() + NumToInsert);
|
||||
size_t NumOverwritten = OldEnd-I;
|
||||
this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
|
||||
|
||||
// Replace the overwritten part.
|
||||
for (; NumOverwritten > 0; --NumOverwritten) {
|
||||
*I = *From;
|
||||
++I; ++From;
|
||||
}
|
||||
|
||||
// Insert the non-overwritten middle part.
|
||||
this->uninitialized_copy(From, To, OldEnd);
|
||||
return I;
|
||||
}
|
||||
|
||||
void resize(ASTContext &C, unsigned N, const T &NV) {
|
||||
if (N < this->size()) {
|
||||
this->destroy_range(this->begin()+N, this->end());
|
||||
this->setEnd(this->begin()+N);
|
||||
} else if (N > this->size()) {
|
||||
if (this->capacity() < N)
|
||||
this->grow(C, N);
|
||||
construct_range(this->end(), this->begin()+N, NV);
|
||||
this->setEnd(this->begin()+N);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/// grow - double the size of the allocated memory, guaranteeing space for at
|
||||
/// least one more element or MinSize if specified.
|
||||
void grow(ASTContext &C, size_type MinSize = 1);
|
||||
|
||||
void construct_range(T *S, T *E, const T &Elt) {
|
||||
for (; S != E; ++S)
|
||||
new (S) T(Elt);
|
||||
}
|
||||
|
||||
void destroy_range(T *S, T *E) {
|
||||
while (S != E) {
|
||||
--E;
|
||||
E->~T();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
iterator capacity_ptr() { return (iterator)this->Capacity; }
|
||||
};
|
||||
|
||||
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
||||
template <typename T>
|
||||
void ASTVector<T>::grow(ASTContext &C, size_t MinSize) {
|
||||
size_t CurCapacity = Capacity-Begin;
|
||||
size_t CurSize = size();
|
||||
size_t NewCapacity = 2*CurCapacity;
|
||||
if (NewCapacity < MinSize)
|
||||
NewCapacity = MinSize;
|
||||
|
||||
// Allocate the memory from the ASTContext.
|
||||
T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
|
||||
|
||||
// Copy the elements over.
|
||||
if (llvm::is_class<T>::value) {
|
||||
std::uninitialized_copy(Begin, End, NewElts);
|
||||
// Destroy the original elements.
|
||||
destroy_range(Begin, End);
|
||||
}
|
||||
else {
|
||||
// Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
|
||||
memcpy(NewElts, Begin, CurSize * sizeof(T));
|
||||
}
|
||||
|
||||
// ASTContext never frees any memory.
|
||||
Begin = NewElts;
|
||||
End = NewElts+CurSize;
|
||||
Capacity = Begin+NewCapacity;
|
||||
}
|
||||
|
||||
} // end: clang namespace
|
||||
#endif
|
||||
157
thirdparty/clang/include/clang/AST/Attr.h
vendored
Normal file
157
thirdparty/clang/include/clang/AST/Attr.h
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
//===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Attr interface and subclasses.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ATTR_H
|
||||
#define LLVM_CLANG_AST_ATTR_H
|
||||
|
||||
#include "clang/AST/AttrIterator.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/AttrKinds.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class IdentifierInfo;
|
||||
class ObjCInterfaceDecl;
|
||||
class Expr;
|
||||
class QualType;
|
||||
class FunctionDecl;
|
||||
class TypeSourceInfo;
|
||||
|
||||
/// Attr - This represents one attribute.
|
||||
class Attr {
|
||||
private:
|
||||
SourceRange Range;
|
||||
unsigned AttrKind : 16;
|
||||
|
||||
protected:
|
||||
/// An index into the spelling list of an
|
||||
/// attribute defined in Attr.td file.
|
||||
unsigned SpellingListIndex : 4;
|
||||
|
||||
bool Inherited : 1;
|
||||
|
||||
bool IsPackExpansion : 1;
|
||||
|
||||
virtual ~Attr();
|
||||
|
||||
void* operator new(size_t bytes) throw() {
|
||||
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
|
||||
}
|
||||
void operator delete(void* data) throw() {
|
||||
llvm_unreachable("Attrs cannot be released with regular 'delete'.");
|
||||
}
|
||||
|
||||
public:
|
||||
// Forward so that the regular new and delete do not hide global ones.
|
||||
void* operator new(size_t Bytes, ASTContext &C,
|
||||
size_t Alignment = 16) throw() {
|
||||
return ::operator new(Bytes, C, Alignment);
|
||||
}
|
||||
void operator delete(void *Ptr, ASTContext &C,
|
||||
size_t Alignment) throw() {
|
||||
return ::operator delete(Ptr, C, Alignment);
|
||||
}
|
||||
|
||||
protected:
|
||||
Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
|
||||
: Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
|
||||
Inherited(false), IsPackExpansion(false) {}
|
||||
|
||||
public:
|
||||
|
||||
attr::Kind getKind() const {
|
||||
return static_cast<attr::Kind>(AttrKind);
|
||||
}
|
||||
|
||||
unsigned getSpellingListIndex() const { return SpellingListIndex; }
|
||||
|
||||
SourceLocation getLocation() const { return Range.getBegin(); }
|
||||
SourceRange getRange() const { return Range; }
|
||||
void setRange(SourceRange R) { Range = R; }
|
||||
|
||||
bool isInherited() const { return Inherited; }
|
||||
|
||||
void setPackExpansion(bool PE) { IsPackExpansion = PE; }
|
||||
bool isPackExpansion() const { return IsPackExpansion; }
|
||||
|
||||
// Clone this attribute.
|
||||
virtual Attr *clone(ASTContext &C) const = 0;
|
||||
|
||||
virtual bool isLateParsed() const { return false; }
|
||||
|
||||
// Pretty print this attribute.
|
||||
virtual void printPretty(raw_ostream &OS,
|
||||
const PrintingPolicy &Policy) const = 0;
|
||||
};
|
||||
|
||||
class InheritableAttr : public Attr {
|
||||
virtual void anchor();
|
||||
protected:
|
||||
InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
|
||||
: Attr(AK, R, SpellingListIndex) {}
|
||||
|
||||
public:
|
||||
void setInherited(bool I) { Inherited = I; }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() <= attr::LAST_INHERITABLE;
|
||||
}
|
||||
};
|
||||
|
||||
class InheritableParamAttr : public InheritableAttr {
|
||||
virtual void anchor();
|
||||
protected:
|
||||
InheritableParamAttr(attr::Kind AK, SourceRange R,
|
||||
unsigned SpellingListIndex = 0)
|
||||
: InheritableAttr(AK, R, SpellingListIndex) {}
|
||||
|
||||
public:
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
// Relies on relative order of enum emission with respect to MS inheritance
|
||||
// attrs.
|
||||
return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
|
||||
}
|
||||
};
|
||||
|
||||
class MSInheritanceAttr : public InheritableAttr {
|
||||
virtual void anchor();
|
||||
protected:
|
||||
MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
|
||||
: InheritableAttr(AK, R, SpellingListIndex) {}
|
||||
|
||||
public:
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
// Relies on relative order of enum emission with respect to param attrs.
|
||||
return (A->getKind() <= attr::LAST_MS_INHERITABLE &&
|
||||
A->getKind() > attr::LAST_INHERITABLE_PARAM);
|
||||
}
|
||||
};
|
||||
|
||||
#include "clang/AST/Attrs.inc"
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
142
thirdparty/clang/include/clang/AST/AttrIterator.h
vendored
Normal file
142
thirdparty/clang/include/clang/AST/AttrIterator.h
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
//===--- AttrIterator.h - Classes for attribute iteration -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Attr vector and specific_attr_iterator interfaces.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ATTRITERATOR_H
|
||||
#define LLVM_CLANG_AST_ATTRITERATOR_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class Attr;
|
||||
}
|
||||
|
||||
// Defined in ASTContext.h
|
||||
void *operator new(size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment = 16);
|
||||
// FIXME: Being forced to not have a default argument here due to redeclaration
|
||||
// rules on default arguments sucks
|
||||
void *operator new[](size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment);
|
||||
|
||||
// It is good practice to pair new/delete operators. Also, MSVC gives many
|
||||
// warnings if a matching delete overload is not declared, even though the
|
||||
// throw() spec guarantees it will not be implicitly called.
|
||||
void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
|
||||
void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
|
||||
typedef SmallVector<Attr*, 2> AttrVec;
|
||||
typedef SmallVector<const Attr*, 2> ConstAttrVec;
|
||||
|
||||
/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
|
||||
/// providing attributes that are of a specifc type.
|
||||
template <typename SpecificAttr, typename Container = AttrVec>
|
||||
class specific_attr_iterator {
|
||||
typedef typename Container::const_iterator Iterator;
|
||||
|
||||
/// Current - The current, underlying iterator.
|
||||
/// In order to ensure we don't dereference an invalid iterator unless
|
||||
/// specifically requested, we don't necessarily advance this all the
|
||||
/// way. Instead, we advance it when an operation is requested; if the
|
||||
/// operation is acting on what should be a past-the-end iterator,
|
||||
/// then we offer no guarantees, but this way we do not dererence a
|
||||
/// past-the-end iterator when we move to a past-the-end position.
|
||||
mutable Iterator Current;
|
||||
|
||||
void AdvanceToNext() const {
|
||||
while (!isa<SpecificAttr>(*Current))
|
||||
++Current;
|
||||
}
|
||||
|
||||
void AdvanceToNext(Iterator I) const {
|
||||
while (Current != I && !isa<SpecificAttr>(*Current))
|
||||
++Current;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef SpecificAttr* value_type;
|
||||
typedef SpecificAttr* reference;
|
||||
typedef SpecificAttr* pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
specific_attr_iterator() : Current() { }
|
||||
explicit specific_attr_iterator(Iterator i) : Current(i) { }
|
||||
|
||||
reference operator*() const {
|
||||
AdvanceToNext();
|
||||
return cast<SpecificAttr>(*Current);
|
||||
}
|
||||
pointer operator->() const {
|
||||
AdvanceToNext();
|
||||
return cast<SpecificAttr>(*Current);
|
||||
}
|
||||
|
||||
specific_attr_iterator& operator++() {
|
||||
++Current;
|
||||
return *this;
|
||||
}
|
||||
specific_attr_iterator operator++(int) {
|
||||
specific_attr_iterator Tmp(*this);
|
||||
++(*this);
|
||||
return Tmp;
|
||||
}
|
||||
|
||||
friend bool operator==(specific_attr_iterator Left,
|
||||
specific_attr_iterator Right) {
|
||||
assert((Left.Current == 0) == (Right.Current == 0));
|
||||
if (Left.Current < Right.Current)
|
||||
Left.AdvanceToNext(Right.Current);
|
||||
else
|
||||
Right.AdvanceToNext(Left.Current);
|
||||
return Left.Current == Right.Current;
|
||||
}
|
||||
friend bool operator!=(specific_attr_iterator Left,
|
||||
specific_attr_iterator Right) {
|
||||
return !(Left == Right);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SpecificAttr, typename Container>
|
||||
inline specific_attr_iterator<SpecificAttr, Container>
|
||||
specific_attr_begin(const Container& container) {
|
||||
return specific_attr_iterator<SpecificAttr, Container>(container.begin());
|
||||
}
|
||||
template <typename SpecificAttr, typename Container>
|
||||
inline specific_attr_iterator<SpecificAttr, Container>
|
||||
specific_attr_end(const Container& container) {
|
||||
return specific_attr_iterator<SpecificAttr, Container>(container.end());
|
||||
}
|
||||
|
||||
template <typename SpecificAttr, typename Container>
|
||||
inline bool hasSpecificAttr(const Container& container) {
|
||||
return specific_attr_begin<SpecificAttr>(container) !=
|
||||
specific_attr_end<SpecificAttr>(container);
|
||||
}
|
||||
template <typename SpecificAttr, typename Container>
|
||||
inline SpecificAttr *getSpecificAttr(const Container& container) {
|
||||
specific_attr_iterator<SpecificAttr, Container> i =
|
||||
specific_attr_begin<SpecificAttr>(container);
|
||||
if (i != specific_attr_end<SpecificAttr>(container))
|
||||
return *i;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
87
thirdparty/clang/include/clang/AST/BaseSubobject.h
vendored
Normal file
87
thirdparty/clang/include/clang/AST/BaseSubobject.h
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides a definition of the BaseSubobject class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H
|
||||
#define LLVM_CLANG_AST_BASESUBOBJECT_H
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
|
||||
namespace clang {
|
||||
class CXXRecordDecl;
|
||||
|
||||
// BaseSubobject - Uniquely identifies a direct or indirect base class.
|
||||
// Stores both the base class decl and the offset from the most derived class to
|
||||
// the base class. Used for vtable and VTT generation.
|
||||
class BaseSubobject {
|
||||
/// Base - The base class declaration.
|
||||
const CXXRecordDecl *Base;
|
||||
|
||||
/// BaseOffset - The offset from the most derived class to the base class.
|
||||
CharUnits BaseOffset;
|
||||
|
||||
public:
|
||||
BaseSubobject() { }
|
||||
BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
|
||||
: Base(Base), BaseOffset(BaseOffset) { }
|
||||
|
||||
/// getBase - Returns the base class declaration.
|
||||
const CXXRecordDecl *getBase() const { return Base; }
|
||||
|
||||
/// getBaseOffset - Returns the base class offset.
|
||||
CharUnits getBaseOffset() const { return BaseOffset; }
|
||||
|
||||
friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
|
||||
return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template<> struct DenseMapInfo<clang::BaseSubobject> {
|
||||
static clang::BaseSubobject getEmptyKey() {
|
||||
return clang::BaseSubobject(
|
||||
DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
|
||||
clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
|
||||
}
|
||||
|
||||
static clang::BaseSubobject getTombstoneKey() {
|
||||
return clang::BaseSubobject(
|
||||
DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
|
||||
clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const clang::BaseSubobject &Base) {
|
||||
typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
|
||||
return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
|
||||
Base.getBaseOffset()));
|
||||
}
|
||||
|
||||
static bool isEqual(const clang::BaseSubobject &LHS,
|
||||
const clang::BaseSubobject &RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
// It's OK to treat BaseSubobject as a POD type.
|
||||
template <> struct isPodLike<clang::BaseSubobject> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
240
thirdparty/clang/include/clang/AST/BuiltinTypes.def
vendored
Normal file
240
thirdparty/clang/include/clang/AST/BuiltinTypes.def
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
//===-- BuiltinTypeNodes.def - Metadata about BuiltinTypes ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the database about various builtin singleton types.
|
||||
//
|
||||
// BuiltinType::Id is the enumerator defining the type.
|
||||
//
|
||||
// Context.SingletonId is the global singleton of this type. Some global
|
||||
// singletons are shared by multiple types.
|
||||
//
|
||||
// BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been
|
||||
// covered by any other #define. Defining this macro covers all
|
||||
// the builtins.
|
||||
//
|
||||
// SIGNED_TYPE(Id, SingletonId) - A signed integral type.
|
||||
//
|
||||
// UNSIGNED_TYPE(Id, SingletonId) - An unsigned integral type.
|
||||
//
|
||||
// FLOATING_TYPE(Id, SingletonId) - A floating-point type.
|
||||
//
|
||||
// PLACEHOLDER_TYPE(Id, SingletonId) - A placeholder type. Placeholder
|
||||
// types are used to perform context-sensitive checking of specific
|
||||
// forms of expression.
|
||||
//
|
||||
// SHARED_SINGLETON_TYPE(Expansion) - The given expansion corresponds
|
||||
// to a builtin which uses a shared singleton type.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SIGNED_TYPE
|
||||
#define SIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
|
||||
#endif
|
||||
|
||||
#ifndef UNSIGNED_TYPE
|
||||
#define UNSIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
|
||||
#endif
|
||||
|
||||
#ifndef FLOATING_TYPE
|
||||
#define FLOATING_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
|
||||
#endif
|
||||
|
||||
#ifndef PLACEHOLDER_TYPE
|
||||
#define PLACEHOLDER_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
|
||||
#endif
|
||||
|
||||
#ifndef SHARED_SINGLETON_TYPE
|
||||
#define SHARED_SINGLETON_TYPE(Expansion) Expansion
|
||||
#endif
|
||||
|
||||
//===- Builtin Types ------------------------------------------------------===//
|
||||
|
||||
// void
|
||||
BUILTIN_TYPE(Void, VoidTy)
|
||||
|
||||
//===- Unsigned Types -----------------------------------------------------===//
|
||||
|
||||
// 'bool' in C++, '_Bool' in C99
|
||||
UNSIGNED_TYPE(Bool, BoolTy)
|
||||
|
||||
// 'char' for targets where it's unsigned
|
||||
SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(Char_U, CharTy))
|
||||
|
||||
// 'unsigned char', explicitly qualified
|
||||
UNSIGNED_TYPE(UChar, UnsignedCharTy)
|
||||
|
||||
// 'wchar_t' for targets where it's unsigned
|
||||
SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
|
||||
|
||||
// 'char16_t' in C++
|
||||
UNSIGNED_TYPE(Char16, Char16Ty)
|
||||
|
||||
// 'char32_t' in C++
|
||||
UNSIGNED_TYPE(Char32, Char32Ty)
|
||||
|
||||
// 'unsigned short'
|
||||
UNSIGNED_TYPE(UShort, UnsignedShortTy)
|
||||
|
||||
// 'unsigned int'
|
||||
UNSIGNED_TYPE(UInt, UnsignedIntTy)
|
||||
|
||||
// 'unsigned long'
|
||||
UNSIGNED_TYPE(ULong, UnsignedLongTy)
|
||||
|
||||
// 'unsigned long long'
|
||||
UNSIGNED_TYPE(ULongLong, UnsignedLongLongTy)
|
||||
|
||||
// '__uint128_t'
|
||||
UNSIGNED_TYPE(UInt128, UnsignedInt128Ty)
|
||||
|
||||
//===- Signed Types -------------------------------------------------------===//
|
||||
|
||||
// 'char' for targets where it's signed
|
||||
SHARED_SINGLETON_TYPE(SIGNED_TYPE(Char_S, CharTy))
|
||||
|
||||
// 'signed char', explicitly qualified
|
||||
SIGNED_TYPE(SChar, SignedCharTy)
|
||||
|
||||
// 'wchar_t' for targets where it's signed
|
||||
SHARED_SINGLETON_TYPE(SIGNED_TYPE(WChar_S, WCharTy))
|
||||
|
||||
// 'short' or 'signed short'
|
||||
SIGNED_TYPE(Short, ShortTy)
|
||||
|
||||
// 'int' or 'signed int'
|
||||
SIGNED_TYPE(Int, IntTy)
|
||||
|
||||
// 'long' or 'signed long'
|
||||
SIGNED_TYPE(Long, LongTy)
|
||||
|
||||
// 'long long' or 'signed long long'
|
||||
SIGNED_TYPE(LongLong, LongLongTy)
|
||||
|
||||
// '__int128_t'
|
||||
SIGNED_TYPE(Int128, Int128Ty)
|
||||
|
||||
//===- Floating point types -----------------------------------------------===//
|
||||
|
||||
// 'half' in OpenCL, '__fp16' in ARM NEON.
|
||||
FLOATING_TYPE(Half, HalfTy)
|
||||
|
||||
// 'float'
|
||||
FLOATING_TYPE(Float, FloatTy)
|
||||
|
||||
// 'double'
|
||||
FLOATING_TYPE(Double, DoubleTy)
|
||||
|
||||
// 'long double'
|
||||
FLOATING_TYPE(LongDouble, LongDoubleTy)
|
||||
|
||||
//===- Language-specific types --------------------------------------------===//
|
||||
|
||||
// This is the type of C++0x 'nullptr'.
|
||||
BUILTIN_TYPE(NullPtr, NullPtrTy)
|
||||
|
||||
// The primitive Objective C 'id' type. The user-visible 'id'
|
||||
// type is a typedef of an ObjCObjectPointerType to an
|
||||
// ObjCObjectType with this as its base. In fact, this only ever
|
||||
// shows up in an AST as the base type of an ObjCObjectType.
|
||||
BUILTIN_TYPE(ObjCId, ObjCBuiltinIdTy)
|
||||
|
||||
// The primitive Objective C 'Class' type. The user-visible
|
||||
// 'Class' type is a typedef of an ObjCObjectPointerType to an
|
||||
// ObjCObjectType with this as its base. In fact, this only ever
|
||||
// shows up in an AST as the base type of an ObjCObjectType.
|
||||
BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
|
||||
|
||||
// The primitive Objective C 'SEL' type. The user-visible 'SEL'
|
||||
// type is a typedef of a PointerType to this.
|
||||
BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
|
||||
|
||||
// OpenCL image types.
|
||||
BUILTIN_TYPE(OCLImage1d, OCLImage1dTy)
|
||||
BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy)
|
||||
BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy)
|
||||
BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
|
||||
BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
|
||||
BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
|
||||
|
||||
// OpenCL sampler_t.
|
||||
BUILTIN_TYPE(OCLSampler, OCLSamplerTy)
|
||||
|
||||
// OpenCL event_t.
|
||||
BUILTIN_TYPE(OCLEvent, OCLEventTy)
|
||||
|
||||
// This represents the type of an expression whose type is
|
||||
// totally unknown, e.g. 'T::foo'. It is permitted for this to
|
||||
// appear in situations where the structure of the type is
|
||||
// theoretically deducible.
|
||||
BUILTIN_TYPE(Dependent, DependentTy)
|
||||
|
||||
// The type of an unresolved overload set. A placeholder type.
|
||||
// Expressions with this type have one of the following basic
|
||||
// forms, with parentheses generally permitted:
|
||||
// foo # possibly qualified, not if an implicit access
|
||||
// foo # possibly qualified, not if an implicit access
|
||||
// &foo # possibly qualified, not if an implicit access
|
||||
// x->foo # only if might be a static member function
|
||||
// &x->foo # only if might be a static member function
|
||||
// &Class::foo # when a pointer-to-member; sub-expr also has this type
|
||||
// OverloadExpr::find can be used to analyze the expression.
|
||||
//
|
||||
// Overload should be the first placeholder type, or else change
|
||||
// BuiltinType::isNonOverloadPlaceholderType()
|
||||
PLACEHOLDER_TYPE(Overload, OverloadTy)
|
||||
|
||||
// The type of a bound C++ non-static member function.
|
||||
// A placeholder type. Expressions with this type have one of the
|
||||
// following basic forms:
|
||||
// foo # if an implicit access
|
||||
// x->foo # if only contains non-static members
|
||||
PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)
|
||||
|
||||
// The type of an expression which refers to a pseudo-object,
|
||||
// such as those introduced by Objective C's @property or
|
||||
// VS.NET's __property declarations. A placeholder type. The
|
||||
// pseudo-object is actually accessed by emitting a call to
|
||||
// some sort of function or method; typically there is a pair
|
||||
// of a setter and a getter, with the setter used if the
|
||||
// pseudo-object reference is used syntactically as the
|
||||
// left-hand-side of an assignment operator.
|
||||
//
|
||||
// A pseudo-object reference naming an Objective-C @property is
|
||||
// always a dot access with a base of object-pointer type,
|
||||
// e.g. 'x.foo'.
|
||||
//
|
||||
// In VS.NET, a __property declaration creates an implicit
|
||||
// member with an associated name, which can then be named
|
||||
// in any of the normal ways an ordinary member could be.
|
||||
PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy)
|
||||
|
||||
// __builtin_any_type. A placeholder type. Useful for clients
|
||||
// like debuggers that don't know what type to give something.
|
||||
// Only a small number of operations are valid on expressions of
|
||||
// unknown type, most notably explicit casts.
|
||||
PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy)
|
||||
|
||||
PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
|
||||
|
||||
// The type of a cast which, in ARC, would normally require a
|
||||
// __bridge, but which might be okay depending on the immediate
|
||||
// context.
|
||||
PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
|
||||
|
||||
#ifdef LAST_BUILTIN_TYPE
|
||||
LAST_BUILTIN_TYPE(ARCUnbridgedCast)
|
||||
#undef LAST_BUILTIN_TYPE
|
||||
#endif
|
||||
|
||||
#undef SHARED_SINGLETON_TYPE
|
||||
#undef PLACEHOLDER_TYPE
|
||||
#undef FLOATING_TYPE
|
||||
#undef SIGNED_TYPE
|
||||
#undef UNSIGNED_TYPE
|
||||
#undef BUILTIN_TYPE
|
||||
368
thirdparty/clang/include/clang/AST/CXXInheritance.h
vendored
Normal file
368
thirdparty/clang/include/clang/AST/CXXInheritance.h
vendored
Normal file
@@ -0,0 +1,368 @@
|
||||
//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides routines that help analyzing C++ inheritance hierarchies.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
|
||||
#define LLVM_CLANG_AST_CXXINHERITANCE_H
|
||||
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/TypeOrdering.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CXXBaseSpecifier;
|
||||
class CXXMethodDecl;
|
||||
class CXXRecordDecl;
|
||||
class NamedDecl;
|
||||
|
||||
/// \brief Represents an element in a path from a derived class to a
|
||||
/// base class.
|
||||
///
|
||||
/// Each step in the path references the link from a
|
||||
/// derived class to one of its direct base classes, along with a
|
||||
/// base "number" that identifies which base subobject of the
|
||||
/// original derived class we are referencing.
|
||||
struct CXXBasePathElement {
|
||||
/// \brief The base specifier that states the link from a derived
|
||||
/// class to a base class, which will be followed by this base
|
||||
/// path element.
|
||||
const CXXBaseSpecifier *Base;
|
||||
|
||||
/// \brief The record decl of the class that the base is a base of.
|
||||
const CXXRecordDecl *Class;
|
||||
|
||||
/// \brief Identifies which base class subobject (of type
|
||||
/// \c Base->getType()) this base path element refers to.
|
||||
///
|
||||
/// This value is only valid if \c !Base->isVirtual(), because there
|
||||
/// is no base numbering for the zero or one virtual bases of a
|
||||
/// given type.
|
||||
int SubobjectNumber;
|
||||
};
|
||||
|
||||
/// \brief Represents a path from a specific derived class
|
||||
/// (which is not represented as part of the path) to a particular
|
||||
/// (direct or indirect) base class subobject.
|
||||
///
|
||||
/// Individual elements in the path are described by the \c CXXBasePathElement
|
||||
/// structure, which captures both the link from a derived class to one of its
|
||||
/// direct bases and identification describing which base class
|
||||
/// subobject is being used.
|
||||
class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
|
||||
public:
|
||||
CXXBasePath() : Access(AS_public) {}
|
||||
|
||||
/// \brief The access along this inheritance path. This is only
|
||||
/// calculated when recording paths. AS_none is a special value
|
||||
/// used to indicate a path which permits no legal access.
|
||||
AccessSpecifier Access;
|
||||
|
||||
/// \brief The set of declarations found inside this base class
|
||||
/// subobject.
|
||||
DeclContext::lookup_result Decls;
|
||||
|
||||
void clear() {
|
||||
SmallVectorImpl<CXXBasePathElement>::clear();
|
||||
Access = AS_public;
|
||||
}
|
||||
};
|
||||
|
||||
/// BasePaths - Represents the set of paths from a derived class to
|
||||
/// one of its (direct or indirect) bases. For example, given the
|
||||
/// following class hierarchy:
|
||||
///
|
||||
/// @code
|
||||
/// class A { };
|
||||
/// class B : public A { };
|
||||
/// class C : public A { };
|
||||
/// class D : public B, public C{ };
|
||||
/// @endcode
|
||||
///
|
||||
/// There are two potential BasePaths to represent paths from D to a
|
||||
/// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
|
||||
/// and another is (D,0)->(C,0)->(A,1). These two paths actually
|
||||
/// refer to two different base class subobjects of the same type,
|
||||
/// so the BasePaths object refers to an ambiguous path. On the
|
||||
/// other hand, consider the following class hierarchy:
|
||||
///
|
||||
/// @code
|
||||
/// class A { };
|
||||
/// class B : public virtual A { };
|
||||
/// class C : public virtual A { };
|
||||
/// class D : public B, public C{ };
|
||||
/// @endcode
|
||||
///
|
||||
/// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
|
||||
/// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
|
||||
/// refer to the same base class subobject of type A (the virtual
|
||||
/// one), there is no ambiguity.
|
||||
class CXXBasePaths {
|
||||
/// \brief The type from which this search originated.
|
||||
CXXRecordDecl *Origin;
|
||||
|
||||
/// Paths - The actual set of paths that can be taken from the
|
||||
/// derived class to the same base class.
|
||||
std::list<CXXBasePath> Paths;
|
||||
|
||||
/// ClassSubobjects - Records the class subobjects for each class
|
||||
/// type that we've seen. The first element in the pair says
|
||||
/// whether we found a path to a virtual base for that class type,
|
||||
/// while the element contains the number of non-virtual base
|
||||
/// class subobjects for that class type. The key of the map is
|
||||
/// the cv-unqualified canonical type of the base class subobject.
|
||||
llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
|
||||
|
||||
/// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
|
||||
/// ambiguous paths while it is looking for a path from a derived
|
||||
/// type to a base type.
|
||||
bool FindAmbiguities;
|
||||
|
||||
/// RecordPaths - Whether Sema::IsDerivedFrom should record paths
|
||||
/// while it is determining whether there are paths from a derived
|
||||
/// type to a base type.
|
||||
bool RecordPaths;
|
||||
|
||||
/// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search
|
||||
/// if it finds a path that goes across a virtual base. The virtual class
|
||||
/// is also recorded.
|
||||
bool DetectVirtual;
|
||||
|
||||
/// ScratchPath - A BasePath that is used by Sema::lookupInBases
|
||||
/// to help build the set of paths.
|
||||
CXXBasePath ScratchPath;
|
||||
|
||||
/// DetectedVirtual - The base class that is virtual.
|
||||
const RecordType *DetectedVirtual;
|
||||
|
||||
/// \brief Array of the declarations that have been found. This
|
||||
/// array is constructed only if needed, e.g., to iterate over the
|
||||
/// results within LookupResult.
|
||||
NamedDecl **DeclsFound;
|
||||
unsigned NumDeclsFound;
|
||||
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
void ComputeDeclsFound();
|
||||
|
||||
bool lookupInBases(ASTContext &Context,
|
||||
const CXXRecordDecl *Record,
|
||||
CXXRecordDecl::BaseMatchesCallback *BaseMatches,
|
||||
void *UserData);
|
||||
public:
|
||||
typedef std::list<CXXBasePath>::iterator paths_iterator;
|
||||
typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
|
||||
typedef NamedDecl **decl_iterator;
|
||||
|
||||
/// BasePaths - Construct a new BasePaths structure to record the
|
||||
/// paths for a derived-to-base search.
|
||||
explicit CXXBasePaths(bool FindAmbiguities = true,
|
||||
bool RecordPaths = true,
|
||||
bool DetectVirtual = true)
|
||||
: FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
|
||||
DetectVirtual(DetectVirtual), DetectedVirtual(0), DeclsFound(0),
|
||||
NumDeclsFound(0) { }
|
||||
|
||||
~CXXBasePaths() { delete [] DeclsFound; }
|
||||
|
||||
paths_iterator begin() { return Paths.begin(); }
|
||||
paths_iterator end() { return Paths.end(); }
|
||||
const_paths_iterator begin() const { return Paths.begin(); }
|
||||
const_paths_iterator end() const { return Paths.end(); }
|
||||
|
||||
CXXBasePath& front() { return Paths.front(); }
|
||||
const CXXBasePath& front() const { return Paths.front(); }
|
||||
|
||||
decl_iterator found_decls_begin();
|
||||
decl_iterator found_decls_end();
|
||||
|
||||
/// \brief Determine whether the path from the most-derived type to the
|
||||
/// given base type is ambiguous (i.e., it refers to multiple subobjects of
|
||||
/// the same base type).
|
||||
bool isAmbiguous(CanQualType BaseType);
|
||||
|
||||
/// \brief Whether we are finding multiple paths to detect ambiguities.
|
||||
bool isFindingAmbiguities() const { return FindAmbiguities; }
|
||||
|
||||
/// \brief Whether we are recording paths.
|
||||
bool isRecordingPaths() const { return RecordPaths; }
|
||||
|
||||
/// \brief Specify whether we should be recording paths or not.
|
||||
void setRecordingPaths(bool RP) { RecordPaths = RP; }
|
||||
|
||||
/// \brief Whether we are detecting virtual bases.
|
||||
bool isDetectingVirtual() const { return DetectVirtual; }
|
||||
|
||||
/// \brief The virtual base discovered on the path (if we are merely
|
||||
/// detecting virtuals).
|
||||
const RecordType* getDetectedVirtual() const {
|
||||
return DetectedVirtual;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the type from which this base-paths search
|
||||
/// began
|
||||
CXXRecordDecl *getOrigin() const { return Origin; }
|
||||
void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
|
||||
|
||||
/// \brief Clear the base-paths results.
|
||||
void clear();
|
||||
|
||||
/// \brief Swap this data structure's contents with another CXXBasePaths
|
||||
/// object.
|
||||
void swap(CXXBasePaths &Other);
|
||||
};
|
||||
|
||||
/// \brief Uniquely identifies a virtual method within a class
|
||||
/// hierarchy by the method itself and a class subobject number.
|
||||
struct UniqueVirtualMethod {
|
||||
UniqueVirtualMethod() : Method(0), Subobject(0), InVirtualSubobject(0) { }
|
||||
|
||||
UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
|
||||
const CXXRecordDecl *InVirtualSubobject)
|
||||
: Method(Method), Subobject(Subobject),
|
||||
InVirtualSubobject(InVirtualSubobject) { }
|
||||
|
||||
/// \brief The overriding virtual method.
|
||||
CXXMethodDecl *Method;
|
||||
|
||||
/// \brief The subobject in which the overriding virtual method
|
||||
/// resides.
|
||||
unsigned Subobject;
|
||||
|
||||
/// \brief The virtual base class subobject of which this overridden
|
||||
/// virtual method is a part. Note that this records the closest
|
||||
/// derived virtual base class subobject.
|
||||
const CXXRecordDecl *InVirtualSubobject;
|
||||
|
||||
friend bool operator==(const UniqueVirtualMethod &X,
|
||||
const UniqueVirtualMethod &Y) {
|
||||
return X.Method == Y.Method && X.Subobject == Y.Subobject &&
|
||||
X.InVirtualSubobject == Y.InVirtualSubobject;
|
||||
}
|
||||
|
||||
friend bool operator!=(const UniqueVirtualMethod &X,
|
||||
const UniqueVirtualMethod &Y) {
|
||||
return !(X == Y);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief The set of methods that override a given virtual method in
|
||||
/// each subobject where it occurs.
|
||||
///
|
||||
/// The first part of the pair is the subobject in which the
|
||||
/// overridden virtual function occurs, while the second part of the
|
||||
/// pair is the virtual method that overrides it (including the
|
||||
/// subobject in which that virtual function occurs).
|
||||
class OverridingMethods {
|
||||
typedef SmallVector<UniqueVirtualMethod, 4> ValuesT;
|
||||
typedef llvm::MapVector<unsigned, ValuesT> MapType;
|
||||
MapType Overrides;
|
||||
|
||||
public:
|
||||
// Iterate over the set of subobjects that have overriding methods.
|
||||
typedef MapType::iterator iterator;
|
||||
typedef MapType::const_iterator const_iterator;
|
||||
iterator begin() { return Overrides.begin(); }
|
||||
const_iterator begin() const { return Overrides.begin(); }
|
||||
iterator end() { return Overrides.end(); }
|
||||
const_iterator end() const { return Overrides.end(); }
|
||||
unsigned size() const { return Overrides.size(); }
|
||||
|
||||
// Iterate over the set of overriding virtual methods in a given
|
||||
// subobject.
|
||||
typedef SmallVector<UniqueVirtualMethod, 4>::iterator
|
||||
overriding_iterator;
|
||||
typedef SmallVector<UniqueVirtualMethod, 4>::const_iterator
|
||||
overriding_const_iterator;
|
||||
|
||||
// Add a new overriding method for a particular subobject.
|
||||
void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
|
||||
|
||||
// Add all of the overriding methods from "other" into overrides for
|
||||
// this method. Used when merging the overrides from multiple base
|
||||
// class subobjects.
|
||||
void add(const OverridingMethods &Other);
|
||||
|
||||
// Replace all overriding virtual methods in all subobjects with the
|
||||
// given virtual method.
|
||||
void replaceAll(UniqueVirtualMethod Overriding);
|
||||
};
|
||||
|
||||
/// \brief A mapping from each virtual member function to its set of
|
||||
/// final overriders.
|
||||
///
|
||||
/// Within a class hierarchy for a given derived class, each virtual
|
||||
/// member function in that hierarchy has one or more "final
|
||||
/// overriders" (C++ [class.virtual]p2). A final overrider for a
|
||||
/// virtual function "f" is the virtual function that will actually be
|
||||
/// invoked when dispatching a call to "f" through the
|
||||
/// vtable. Well-formed classes have a single final overrider for each
|
||||
/// virtual function; in abstract classes, the final overrider for at
|
||||
/// least one virtual function is a pure virtual function. Due to
|
||||
/// multiple, virtual inheritance, it is possible for a class to have
|
||||
/// more than one final overrider. Athough this is an error (per C++
|
||||
/// [class.virtual]p2), it is not considered an error here: the final
|
||||
/// overrider map can represent multiple final overriders for a
|
||||
/// method, and it is up to the client to determine whether they are
|
||||
/// problem. For example, the following class \c D has two final
|
||||
/// overriders for the virtual function \c A::f(), one in \c C and one
|
||||
/// in \c D:
|
||||
///
|
||||
/// \code
|
||||
/// struct A { virtual void f(); };
|
||||
/// struct B : virtual A { virtual void f(); };
|
||||
/// struct C : virtual A { virtual void f(); };
|
||||
/// struct D : B, C { };
|
||||
/// \endcode
|
||||
///
|
||||
/// This data structure contaings a mapping from every virtual
|
||||
/// function *that does not override an existing virtual function* and
|
||||
/// in every subobject where that virtual function occurs to the set
|
||||
/// of virtual functions that override it. Thus, the same virtual
|
||||
/// function \c A::f can actually occur in multiple subobjects of type
|
||||
/// \c A due to multiple inheritance, and may be overriden by
|
||||
/// different virtual functions in each, as in the following example:
|
||||
///
|
||||
/// \code
|
||||
/// struct A { virtual void f(); };
|
||||
/// struct B : A { virtual void f(); };
|
||||
/// struct C : A { virtual void f(); };
|
||||
/// struct D : B, C { };
|
||||
/// \endcode
|
||||
///
|
||||
/// Unlike in the previous example, where the virtual functions \c
|
||||
/// B::f and \c C::f both overrode \c A::f in the same subobject of
|
||||
/// type \c A, in this example the two virtual functions both override
|
||||
/// \c A::f but in *different* subobjects of type A. This is
|
||||
/// represented by numbering the subobjects in which the overridden
|
||||
/// and the overriding virtual member functions are located. Subobject
|
||||
/// 0 represents the virtua base class subobject of that type, while
|
||||
/// subobject numbers greater than 0 refer to non-virtual base class
|
||||
/// subobjects of that type.
|
||||
class CXXFinalOverriderMap
|
||||
: public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { };
|
||||
|
||||
/// \brief A set of all the primary bases for a class.
|
||||
class CXXIndirectPrimaryBaseSet
|
||||
: public llvm::SmallSet<const CXXRecordDecl*, 32> { };
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
740
thirdparty/clang/include/clang/AST/CanonicalType.h
vendored
Normal file
740
thirdparty/clang/include/clang/AST/CanonicalType.h
vendored
Normal file
@@ -0,0 +1,740 @@
|
||||
//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the CanQual class template, which provides access to
|
||||
// canonical types.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
|
||||
#define LLVM_CLANG_AST_CANONICAL_TYPE_H
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
template<typename T> class CanProxy;
|
||||
template<typename T> struct CanProxyAdaptor;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Canonical, qualified type template
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/// \brief Represents a canonical, potentially-qualified type.
|
||||
///
|
||||
/// The CanQual template is a lightweight smart pointer that provides access
|
||||
/// to the canonical representation of a type, where all typedefs and other
|
||||
/// syntactic sugar has been eliminated. A CanQualType may also have various
|
||||
/// qualifiers (const, volatile, restrict) attached to it.
|
||||
///
|
||||
/// The template type parameter @p T is one of the Type classes (PointerType,
|
||||
/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
|
||||
/// type (or some subclass of that type). The typedef @c CanQualType is just
|
||||
/// a shorthand for @c CanQual<Type>.
|
||||
///
|
||||
/// An instance of @c CanQual<T> can be implicitly converted to a
|
||||
/// @c CanQual<U> when T is derived from U, which essentially provides an
|
||||
/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
|
||||
/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
|
||||
/// be implicitly converted to a QualType, but the reverse operation requires
|
||||
/// a call to ASTContext::getCanonicalType().
|
||||
///
|
||||
///
|
||||
template<typename T = Type>
|
||||
class CanQual {
|
||||
/// \brief The actual, canonical type.
|
||||
QualType Stored;
|
||||
|
||||
public:
|
||||
/// \brief Constructs a NULL canonical type.
|
||||
CanQual() : Stored() { }
|
||||
|
||||
/// \brief Converting constructor that permits implicit upcasting of
|
||||
/// canonical type pointers.
|
||||
template<typename U>
|
||||
CanQual(const CanQual<U>& Other,
|
||||
typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
|
||||
|
||||
/// \brief Retrieve the underlying type pointer, which refers to a
|
||||
/// canonical type.
|
||||
///
|
||||
/// The underlying pointer must not be NULL.
|
||||
const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
|
||||
|
||||
/// \brief Retrieve the underlying type pointer, which refers to a
|
||||
/// canonical type, or NULL.
|
||||
///
|
||||
const T *getTypePtrOrNull() const {
|
||||
return cast_or_null<T>(Stored.getTypePtrOrNull());
|
||||
}
|
||||
|
||||
/// \brief Implicit conversion to a qualified type.
|
||||
operator QualType() const { return Stored; }
|
||||
|
||||
/// \brief Implicit conversion to bool.
|
||||
operator bool() const { return !isNull(); }
|
||||
|
||||
bool isNull() const {
|
||||
return Stored.isNull();
|
||||
}
|
||||
|
||||
SplitQualType split() const { return Stored.split(); }
|
||||
|
||||
/// \brief Retrieve a canonical type pointer with a different static type,
|
||||
/// upcasting or downcasting as needed.
|
||||
///
|
||||
/// The getAs() function is typically used to try to downcast to a
|
||||
/// more specific (canonical) type in the type system. For example:
|
||||
///
|
||||
/// @code
|
||||
/// void f(CanQual<Type> T) {
|
||||
/// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
|
||||
/// // look at Ptr's pointee type
|
||||
/// }
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// \returns A proxy pointer to the same type, but with the specified
|
||||
/// static type (@p U). If the dynamic type is not the specified static type
|
||||
/// or a derived class thereof, a NULL canonical type.
|
||||
template<typename U> CanProxy<U> getAs() const;
|
||||
|
||||
template<typename U> CanProxy<U> castAs() const;
|
||||
|
||||
/// \brief Overloaded arrow operator that produces a canonical type
|
||||
/// proxy.
|
||||
CanProxy<T> operator->() const;
|
||||
|
||||
/// \brief Retrieve all qualifiers.
|
||||
Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
|
||||
|
||||
/// \brief Retrieve the const/volatile/restrict qualifiers.
|
||||
unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
|
||||
|
||||
/// \brief Determines whether this type has any qualifiers
|
||||
bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
|
||||
|
||||
bool isConstQualified() const {
|
||||
return Stored.isLocalConstQualified();
|
||||
}
|
||||
bool isVolatileQualified() const {
|
||||
return Stored.isLocalVolatileQualified();
|
||||
}
|
||||
bool isRestrictQualified() const {
|
||||
return Stored.isLocalRestrictQualified();
|
||||
}
|
||||
|
||||
/// \brief Determines if this canonical type is furthermore
|
||||
/// canonical as a parameter. The parameter-canonicalization
|
||||
/// process decays arrays to pointers and drops top-level qualifiers.
|
||||
bool isCanonicalAsParam() const {
|
||||
return Stored.isCanonicalAsParam();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the unqualified form of this type.
|
||||
CanQual<T> getUnqualifiedType() const;
|
||||
|
||||
/// \brief Retrieves a version of this type with const applied.
|
||||
/// Note that this does not always yield a canonical type.
|
||||
QualType withConst() const {
|
||||
return Stored.withConst();
|
||||
}
|
||||
|
||||
/// \brief Determines whether this canonical type is more qualified than
|
||||
/// the @p Other canonical type.
|
||||
bool isMoreQualifiedThan(CanQual<T> Other) const {
|
||||
return Stored.isMoreQualifiedThan(Other.Stored);
|
||||
}
|
||||
|
||||
/// \brief Determines whether this canonical type is at least as qualified as
|
||||
/// the @p Other canonical type.
|
||||
bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
|
||||
return Stored.isAtLeastAsQualifiedAs(Other.Stored);
|
||||
}
|
||||
|
||||
/// \brief If the canonical type is a reference type, returns the type that
|
||||
/// it refers to; otherwise, returns the type itself.
|
||||
CanQual<Type> getNonReferenceType() const;
|
||||
|
||||
/// \brief Retrieve the internal representation of this canonical type.
|
||||
void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
|
||||
|
||||
/// \brief Construct a canonical type from its internal representation.
|
||||
static CanQual<T> getFromOpaquePtr(void *Ptr);
|
||||
|
||||
/// \brief Builds a canonical type from a QualType.
|
||||
///
|
||||
/// This routine is inherently unsafe, because it requires the user to
|
||||
/// ensure that the given type is a canonical type with the correct
|
||||
// (dynamic) type.
|
||||
static CanQual<T> CreateUnsafe(QualType Other);
|
||||
|
||||
void dump() const { Stored.dump(); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) const {
|
||||
ID.AddPointer(getAsOpaquePtr());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
inline bool operator==(CanQual<T> x, CanQual<U> y) {
|
||||
return x.getAsOpaquePtr() == y.getAsOpaquePtr();
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline bool operator!=(CanQual<T> x, CanQual<U> y) {
|
||||
return x.getAsOpaquePtr() != y.getAsOpaquePtr();
|
||||
}
|
||||
|
||||
/// \brief Represents a canonical, potentially-qualified type.
|
||||
typedef CanQual<Type> CanQualType;
|
||||
|
||||
inline CanQualType Type::getCanonicalTypeUnqualified() const {
|
||||
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
CanQualType T) {
|
||||
DB << static_cast<QualType>(T);
|
||||
return DB;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Internal proxy classes used by canonical types
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \
|
||||
CanQualType Accessor() const { \
|
||||
return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \
|
||||
}
|
||||
|
||||
#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \
|
||||
Type Accessor() const { return this->getTypePtr()->Accessor(); }
|
||||
|
||||
/// \brief Base class of all canonical proxy types, which is responsible for
|
||||
/// storing the underlying canonical type and providing basic conversions.
|
||||
template<typename T>
|
||||
class CanProxyBase {
|
||||
protected:
|
||||
CanQual<T> Stored;
|
||||
|
||||
public:
|
||||
/// \brief Retrieve the pointer to the underlying Type
|
||||
const T *getTypePtr() const { return Stored.getTypePtr(); }
|
||||
|
||||
/// \brief Implicit conversion to the underlying pointer.
|
||||
///
|
||||
/// Also provides the ability to use canonical type proxies in a Boolean
|
||||
// context,e.g.,
|
||||
/// @code
|
||||
/// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
|
||||
/// @endcode
|
||||
operator const T*() const { return this->Stored.getTypePtrOrNull(); }
|
||||
|
||||
/// \brief Try to convert the given canonical type to a specific structural
|
||||
/// type.
|
||||
template<typename U> CanProxy<U> getAs() const {
|
||||
return this->Stored.template getAs<U>();
|
||||
}
|
||||
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
|
||||
|
||||
// Type predicates
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
|
||||
|
||||
/// \brief Retrieve the proxy-adaptor type.
|
||||
///
|
||||
/// This arrow operator is used when CanProxyAdaptor has been specialized
|
||||
/// for the given type T. In that case, we reference members of the
|
||||
/// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
|
||||
/// by the arrow operator in the primary CanProxyAdaptor template.
|
||||
const CanProxyAdaptor<T> *operator->() const {
|
||||
return static_cast<const CanProxyAdaptor<T> *>(this);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Replacable canonical proxy adaptor class that provides the link
|
||||
/// between a canonical type and the accessors of the type.
|
||||
///
|
||||
/// The CanProxyAdaptor is a replaceable class template that is instantiated
|
||||
/// as part of each canonical proxy type. The primary template merely provides
|
||||
/// redirection to the underlying type (T), e.g., @c PointerType. One can
|
||||
/// provide specializations of this class template for each underlying type
|
||||
/// that provide accessors returning canonical types (@c CanQualType) rather
|
||||
/// than the more typical @c QualType, to propagate the notion of "canonical"
|
||||
/// through the system.
|
||||
template<typename T>
|
||||
struct CanProxyAdaptor : CanProxyBase<T> { };
|
||||
|
||||
/// \brief Canonical proxy type returned when retrieving the members of a
|
||||
/// canonical type or as the result of the @c CanQual<T>::getAs member
|
||||
/// function.
|
||||
///
|
||||
/// The CanProxy type mainly exists as a proxy through which operator-> will
|
||||
/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
|
||||
/// type that provides canonical-type access to the fields of the type.
|
||||
template<typename T>
|
||||
class CanProxy : public CanProxyAdaptor<T> {
|
||||
public:
|
||||
/// \brief Build a NULL proxy.
|
||||
CanProxy() { }
|
||||
|
||||
/// \brief Build a proxy to the given canonical type.
|
||||
CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
|
||||
|
||||
/// \brief Implicit conversion to the stored canonical type.
|
||||
operator CanQual<T>() const { return this->Stored; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
|
||||
/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
|
||||
/// to return smart pointer (proxies?).
|
||||
template<typename T>
|
||||
struct simplify_type< ::clang::CanQual<T> > {
|
||||
typedef const T *SimpleType;
|
||||
static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
|
||||
return Val.getTypePtr();
|
||||
}
|
||||
};
|
||||
|
||||
// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
|
||||
template<typename T>
|
||||
class PointerLikeTypeTraits<clang::CanQual<T> > {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(clang::CanQual<T> P) {
|
||||
return P.getAsOpaquePtr();
|
||||
}
|
||||
static inline clang::CanQual<T> getFromVoidPointer(void *P) {
|
||||
return clang::CanQual<T>::getFromOpaquePtr(P);
|
||||
}
|
||||
// qualifier information is encoded in the low bits.
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Canonical proxy adaptors for canonical type nodes.
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
|
||||
/// into an iterator over CanQualTypes.
|
||||
template<typename InputIterator>
|
||||
class CanTypeIterator {
|
||||
InputIterator Iter;
|
||||
|
||||
public:
|
||||
typedef CanQualType value_type;
|
||||
typedef value_type reference;
|
||||
typedef CanProxy<Type> pointer;
|
||||
typedef typename std::iterator_traits<InputIterator>::difference_type
|
||||
difference_type;
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category
|
||||
iterator_category;
|
||||
|
||||
CanTypeIterator() : Iter() { }
|
||||
explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
|
||||
|
||||
// Input iterator
|
||||
reference operator*() const {
|
||||
return CanQualType::CreateUnsafe(*Iter);
|
||||
}
|
||||
|
||||
pointer operator->() const;
|
||||
|
||||
CanTypeIterator &operator++() {
|
||||
++Iter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CanTypeIterator operator++(int) {
|
||||
CanTypeIterator Tmp(*this);
|
||||
++Iter;
|
||||
return Tmp;
|
||||
}
|
||||
|
||||
friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
|
||||
return X.Iter == Y.Iter;
|
||||
}
|
||||
friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
|
||||
return X.Iter != Y.Iter;
|
||||
}
|
||||
|
||||
// Bidirectional iterator
|
||||
CanTypeIterator &operator--() {
|
||||
--Iter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CanTypeIterator operator--(int) {
|
||||
CanTypeIterator Tmp(*this);
|
||||
--Iter;
|
||||
return Tmp;
|
||||
}
|
||||
|
||||
// Random access iterator
|
||||
reference operator[](difference_type n) const {
|
||||
return CanQualType::CreateUnsafe(Iter[n]);
|
||||
}
|
||||
|
||||
CanTypeIterator &operator+=(difference_type n) {
|
||||
Iter += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CanTypeIterator &operator-=(difference_type n) {
|
||||
Iter -= n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
|
||||
X += n;
|
||||
return X;
|
||||
}
|
||||
|
||||
friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
|
||||
X += n;
|
||||
return X;
|
||||
}
|
||||
|
||||
friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
|
||||
X -= n;
|
||||
return X;
|
||||
}
|
||||
|
||||
friend difference_type operator-(const CanTypeIterator &X,
|
||||
const CanTypeIterator &Y) {
|
||||
return X - Y;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<BlockPointerType>
|
||||
: public CanProxyBase<BlockPointerType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<LValueReferenceType>
|
||||
: public CanProxyBase<LValueReferenceType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<RValueReferenceType>
|
||||
: public CanProxyBase<RValueReferenceType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<MemberPointerType>
|
||||
: public CanProxyBase<MemberPointerType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
|
||||
};
|
||||
|
||||
// CanProxyAdaptors for arrays are intentionally unimplemented because
|
||||
// they are not safe.
|
||||
template<> struct CanProxyAdaptor<ArrayType>;
|
||||
template<> struct CanProxyAdaptor<ConstantArrayType>;
|
||||
template<> struct CanProxyAdaptor<IncompleteArrayType>;
|
||||
template<> struct CanProxyAdaptor<VariableArrayType>;
|
||||
template<> struct CanProxyAdaptor<DependentSizedArrayType>;
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<DependentSizedExtVectorType>
|
||||
: public CanProxyBase<DependentSizedExtVectorType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<FunctionNoProtoType>
|
||||
: public CanProxyBase<FunctionNoProtoType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<FunctionProtoType>
|
||||
: public CanProxyBase<FunctionProtoType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
|
||||
CanQualType getArgType(unsigned i) const {
|
||||
return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
|
||||
}
|
||||
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
|
||||
|
||||
typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
|
||||
arg_type_iterator;
|
||||
|
||||
arg_type_iterator arg_type_begin() const {
|
||||
return arg_type_iterator(this->getTypePtr()->arg_type_begin());
|
||||
}
|
||||
|
||||
arg_type_iterator arg_type_end() const {
|
||||
return arg_type_iterator(this->getTypePtr()->arg_type_end());
|
||||
}
|
||||
|
||||
// Note: canonical function types never have exception specifications
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
|
||||
};
|
||||
|
||||
template <>
|
||||
struct CanProxyAdaptor<UnaryTransformType>
|
||||
: public CanProxyBase<UnaryTransformType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<TemplateTypeParmType>
|
||||
: public CanProxyBase<TemplateTypeParmType> {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<ObjCObjectType>
|
||||
: public CanProxyBase<ObjCObjectType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
|
||||
getInterface)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
|
||||
|
||||
typedef ObjCObjectPointerType::qual_iterator qual_iterator;
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CanProxyAdaptor<ObjCObjectPointerType>
|
||||
: public CanProxyBase<ObjCObjectPointerType> {
|
||||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
|
||||
getInterfaceType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
|
||||
|
||||
typedef ObjCObjectPointerType::qual_iterator qual_iterator;
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Method and function definitions
|
||||
//----------------------------------------------------------------------------//
|
||||
template<typename T>
|
||||
inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
|
||||
return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
|
||||
if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
|
||||
return RefType->getPointeeType();
|
||||
else
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
|
||||
CanQual<T> Result;
|
||||
Result.Stored = QualType::getFromOpaquePtr(Ptr);
|
||||
assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
|
||||
Result.Stored.isCanonical()) && "Type is not canonical!");
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
|
||||
assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
|
||||
assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
|
||||
"Dynamic type does not meet the static type's requires");
|
||||
CanQual<T> Result;
|
||||
Result.Stored = Other;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
CanProxy<U> CanQual<T>::getAs() const {
|
||||
ArrayType_cannot_be_used_with_getAs<U> at;
|
||||
(void)at;
|
||||
|
||||
if (Stored.isNull())
|
||||
return CanProxy<U>();
|
||||
|
||||
if (isa<U>(Stored.getTypePtr()))
|
||||
return CanQual<U>::CreateUnsafe(Stored);
|
||||
|
||||
return CanProxy<U>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
CanProxy<U> CanQual<T>::castAs() const {
|
||||
ArrayType_cannot_be_used_with_getAs<U> at;
|
||||
(void)at;
|
||||
|
||||
assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
|
||||
return CanQual<U>::CreateUnsafe(Stored);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CanProxy<T> CanQual<T>::operator->() const {
|
||||
return CanProxy<T>(*this);
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
typename CanTypeIterator<InputIterator>::pointer
|
||||
CanTypeIterator<InputIterator>::operator->() const {
|
||||
return CanProxy<Type>(*this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
|
||||
228
thirdparty/clang/include/clang/AST/CharUnits.h
vendored
Normal file
228
thirdparty/clang/include/clang/AST/CharUnits.h
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the CharUnits class
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_CHARUNITS_H
|
||||
#define LLVM_CLANG_AST_CHARUNITS_H
|
||||
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// CharUnits - This is an opaque type for sizes expressed in character units.
|
||||
/// Instances of this type represent a quantity as a multiple of the size
|
||||
/// of the standard C type, char, on the target architecture. As an opaque
|
||||
/// type, CharUnits protects you from accidentally combining operations on
|
||||
/// quantities in bit units and character units.
|
||||
///
|
||||
/// It should be noted that characters and bytes are distinct concepts. Bytes
|
||||
/// refer to addressable units of data storage on the target machine, and
|
||||
/// characters are members of a set of elements used for the organization,
|
||||
/// control, or representation of data. According to C99, bytes are allowed
|
||||
/// to exceed characters in size, although currently, clang only supports
|
||||
/// architectures where the two are the same size.
|
||||
///
|
||||
/// For portability, never assume that a target character is 8 bits wide. Use
|
||||
/// CharUnit values wherever you calculate sizes, offsets, or alignments
|
||||
/// in character units.
|
||||
class CharUnits {
|
||||
public:
|
||||
typedef int64_t QuantityType;
|
||||
|
||||
private:
|
||||
QuantityType Quantity;
|
||||
|
||||
explicit CharUnits(QuantityType C) : Quantity(C) {}
|
||||
|
||||
public:
|
||||
|
||||
/// CharUnits - A default constructor.
|
||||
CharUnits() : Quantity(0) {}
|
||||
|
||||
/// Zero - Construct a CharUnits quantity of zero.
|
||||
static CharUnits Zero() {
|
||||
return CharUnits(0);
|
||||
}
|
||||
|
||||
/// One - Construct a CharUnits quantity of one.
|
||||
static CharUnits One() {
|
||||
return CharUnits(1);
|
||||
}
|
||||
|
||||
/// fromQuantity - Construct a CharUnits quantity from a raw integer type.
|
||||
static CharUnits fromQuantity(QuantityType Quantity) {
|
||||
return CharUnits(Quantity);
|
||||
}
|
||||
|
||||
// Compound assignment.
|
||||
CharUnits& operator+= (const CharUnits &Other) {
|
||||
Quantity += Other.Quantity;
|
||||
return *this;
|
||||
}
|
||||
CharUnits& operator++ () {
|
||||
++Quantity;
|
||||
return *this;
|
||||
}
|
||||
CharUnits operator++ (int) {
|
||||
return CharUnits(Quantity++);
|
||||
}
|
||||
CharUnits& operator-= (const CharUnits &Other) {
|
||||
Quantity -= Other.Quantity;
|
||||
return *this;
|
||||
}
|
||||
CharUnits& operator-- () {
|
||||
--Quantity;
|
||||
return *this;
|
||||
}
|
||||
CharUnits operator-- (int) {
|
||||
return CharUnits(Quantity--);
|
||||
}
|
||||
|
||||
// Comparison operators.
|
||||
bool operator== (const CharUnits &Other) const {
|
||||
return Quantity == Other.Quantity;
|
||||
}
|
||||
bool operator!= (const CharUnits &Other) const {
|
||||
return Quantity != Other.Quantity;
|
||||
}
|
||||
|
||||
// Relational operators.
|
||||
bool operator< (const CharUnits &Other) const {
|
||||
return Quantity < Other.Quantity;
|
||||
}
|
||||
bool operator<= (const CharUnits &Other) const {
|
||||
return Quantity <= Other.Quantity;
|
||||
}
|
||||
bool operator> (const CharUnits &Other) const {
|
||||
return Quantity > Other.Quantity;
|
||||
}
|
||||
bool operator>= (const CharUnits &Other) const {
|
||||
return Quantity >= Other.Quantity;
|
||||
}
|
||||
|
||||
// Other predicates.
|
||||
|
||||
/// isZero - Test whether the quantity equals zero.
|
||||
bool isZero() const { return Quantity == 0; }
|
||||
|
||||
/// isOne - Test whether the quantity equals one.
|
||||
bool isOne() const { return Quantity == 1; }
|
||||
|
||||
/// isPositive - Test whether the quantity is greater than zero.
|
||||
bool isPositive() const { return Quantity > 0; }
|
||||
|
||||
/// isNegative - Test whether the quantity is less than zero.
|
||||
bool isNegative() const { return Quantity < 0; }
|
||||
|
||||
/// isPowerOfTwo - Test whether the quantity is a power of two.
|
||||
/// Zero is not a power of two.
|
||||
bool isPowerOfTwo() const {
|
||||
return (Quantity & -Quantity) == Quantity;
|
||||
}
|
||||
|
||||
// Arithmetic operators.
|
||||
CharUnits operator* (QuantityType N) const {
|
||||
return CharUnits(Quantity * N);
|
||||
}
|
||||
CharUnits operator/ (QuantityType N) const {
|
||||
return CharUnits(Quantity / N);
|
||||
}
|
||||
QuantityType operator/ (const CharUnits &Other) const {
|
||||
return Quantity / Other.Quantity;
|
||||
}
|
||||
CharUnits operator% (QuantityType N) const {
|
||||
return CharUnits(Quantity % N);
|
||||
}
|
||||
QuantityType operator% (const CharUnits &Other) const {
|
||||
return Quantity % Other.Quantity;
|
||||
}
|
||||
CharUnits operator+ (const CharUnits &Other) const {
|
||||
return CharUnits(Quantity + Other.Quantity);
|
||||
}
|
||||
CharUnits operator- (const CharUnits &Other) const {
|
||||
return CharUnits(Quantity - Other.Quantity);
|
||||
}
|
||||
CharUnits operator- () const {
|
||||
return CharUnits(-Quantity);
|
||||
}
|
||||
|
||||
|
||||
// Conversions.
|
||||
|
||||
/// getQuantity - Get the raw integer representation of this quantity.
|
||||
QuantityType getQuantity() const { return Quantity; }
|
||||
|
||||
/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
|
||||
/// greater than or equal to this quantity and is a multiple of \p Align.
|
||||
/// Align must be non-zero.
|
||||
CharUnits RoundUpToAlignment(const CharUnits &Align) {
|
||||
return CharUnits(llvm::RoundUpToAlignment(Quantity,
|
||||
Align.Quantity));
|
||||
}
|
||||
|
||||
/// Given that this is a non-zero alignment value, what is the
|
||||
/// alignment at the given offset?
|
||||
CharUnits alignmentAtOffset(CharUnits offset) {
|
||||
// alignment: 0010000
|
||||
// offset: 1011100
|
||||
// lowBits: 0001011
|
||||
// result: 0000100
|
||||
QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
|
||||
return CharUnits((lowBits + 1) & ~lowBits);
|
||||
}
|
||||
|
||||
|
||||
}; // class CharUnit
|
||||
} // namespace clang
|
||||
|
||||
inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
|
||||
const clang::CharUnits &CU) {
|
||||
return CU * Scale;
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template<> struct DenseMapInfo<clang::CharUnits> {
|
||||
static clang::CharUnits getEmptyKey() {
|
||||
clang::CharUnits::QuantityType Quantity =
|
||||
DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
|
||||
|
||||
return clang::CharUnits::fromQuantity(Quantity);
|
||||
}
|
||||
|
||||
static clang::CharUnits getTombstoneKey() {
|
||||
clang::CharUnits::QuantityType Quantity =
|
||||
DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
|
||||
|
||||
return clang::CharUnits::fromQuantity(Quantity);
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const clang::CharUnits &CU) {
|
||||
clang::CharUnits::QuantityType Quantity = CU.getQuantity();
|
||||
return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
|
||||
}
|
||||
|
||||
static bool isEqual(const clang::CharUnits &LHS,
|
||||
const clang::CharUnits &RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct isPodLike<clang::CharUnits> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_CLANG_AST_CHARUNITS_H
|
||||
1111
thirdparty/clang/include/clang/AST/Comment.h
vendored
Normal file
1111
thirdparty/clang/include/clang/AST/Comment.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
55
thirdparty/clang/include/clang/AST/CommentBriefParser.h
vendored
Normal file
55
thirdparty/clang/include/clang/AST/CommentBriefParser.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
//===--- CommentBriefParser.h - Dumb comment parser -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a very simple Doxygen comment parser.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
|
||||
#define LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
|
||||
|
||||
#include "clang/AST/CommentLexer.h"
|
||||
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
/// A very simple comment parser that extracts "a brief description".
|
||||
///
|
||||
/// Due to a variety of comment styles, it considers the following as "a brief
|
||||
/// description", in order of priority:
|
||||
/// \li a \\brief or \\short command,
|
||||
/// \li the first paragraph,
|
||||
/// \li a \\result or \\return or \\returns paragraph.
|
||||
class BriefParser {
|
||||
Lexer &L;
|
||||
|
||||
const CommandTraits &Traits;
|
||||
|
||||
/// Current lookahead token.
|
||||
Token Tok;
|
||||
|
||||
SourceLocation ConsumeToken() {
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
L.lex(Tok);
|
||||
return Loc;
|
||||
}
|
||||
|
||||
public:
|
||||
BriefParser(Lexer &L, const CommandTraits &Traits);
|
||||
|
||||
/// Return the best "brief description" we can find.
|
||||
std::string Parse();
|
||||
};
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
||||
180
thirdparty/clang/include/clang/AST/CommentCommandTraits.h
vendored
Normal file
180
thirdparty/clang/include/clang/AST/CommentCommandTraits.h
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
//===--- CommentCommandTraits.h - Comment command properties ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the class that provides information about comment
|
||||
// commands.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
|
||||
#define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
|
||||
|
||||
#include "clang/Basic/CommentOptions.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
/// \brief Information about a single command.
|
||||
///
|
||||
/// When reordering, adding or removing members please update the corresponding
|
||||
/// TableGen backend.
|
||||
struct CommandInfo {
|
||||
unsigned getID() const {
|
||||
return ID;
|
||||
}
|
||||
|
||||
const char *Name;
|
||||
|
||||
/// Name of the command that ends the verbatim block.
|
||||
const char *EndCommandName;
|
||||
|
||||
unsigned ID : 8;
|
||||
|
||||
/// Number of word-like arguments for a given block command, except for
|
||||
/// \\param and \\tparam commands -- these have special argument parsers.
|
||||
unsigned NumArgs : 4;
|
||||
|
||||
/// True if this command is a inline command (of any kind).
|
||||
unsigned IsInlineCommand : 1;
|
||||
|
||||
/// True if this command is a block command (of any kind).
|
||||
unsigned IsBlockCommand : 1;
|
||||
|
||||
/// True if this command is introducing a brief documentation
|
||||
/// paragraph (\\brief or an alias).
|
||||
unsigned IsBriefCommand : 1;
|
||||
|
||||
/// True if this command is \\returns or an alias.
|
||||
unsigned IsReturnsCommand : 1;
|
||||
|
||||
/// True if this command is introducing documentation for a function
|
||||
/// parameter (\\param or an alias).
|
||||
unsigned IsParamCommand : 1;
|
||||
|
||||
/// True if this command is introducing documentation for
|
||||
/// a template parameter (\\tparam or an alias).
|
||||
unsigned IsTParamCommand : 1;
|
||||
|
||||
/// True if this command is \\deprecated or an alias.
|
||||
unsigned IsDeprecatedCommand : 1;
|
||||
|
||||
/// \brief True if this is a \\headerfile-like command.
|
||||
unsigned IsHeaderfileCommand : 1;
|
||||
|
||||
/// True if we don't want to warn about this command being passed an empty
|
||||
/// paragraph. Meaningful only for block commands.
|
||||
unsigned IsEmptyParagraphAllowed : 1;
|
||||
|
||||
/// \brief True if this command is a verbatim-like block command.
|
||||
///
|
||||
/// A verbatim-like block command eats every character (except line starting
|
||||
/// decorations) until matching end command is seen or comment end is hit.
|
||||
unsigned IsVerbatimBlockCommand : 1;
|
||||
|
||||
/// \brief True if this command is an end command for a verbatim-like block.
|
||||
unsigned IsVerbatimBlockEndCommand : 1;
|
||||
|
||||
/// \brief True if this command is a verbatim line command.
|
||||
///
|
||||
/// A verbatim-like line command eats everything until a newline is seen or
|
||||
/// comment end is hit.
|
||||
unsigned IsVerbatimLineCommand : 1;
|
||||
|
||||
/// \brief True if this command contains a declaration for the entity being
|
||||
/// documented.
|
||||
///
|
||||
/// For example:
|
||||
/// \code
|
||||
/// \fn void f(int a);
|
||||
/// \endcode
|
||||
unsigned IsDeclarationCommand : 1;
|
||||
|
||||
/// \brief True if verbatim-like line command is a function declaration.
|
||||
unsigned IsFunctionDeclarationCommand : 1;
|
||||
|
||||
/// \brief True if block command is further describing a container API; such
|
||||
/// as \@coclass, \@classdesign, etc.
|
||||
unsigned IsRecordLikeDetailCommand : 1;
|
||||
|
||||
/// \brief True if block command is a container API; such as \@interface.
|
||||
unsigned IsRecordLikeDeclarationCommand : 1;
|
||||
|
||||
/// \brief True if this command is unknown. This \c CommandInfo object was
|
||||
/// created during parsing.
|
||||
unsigned IsUnknownCommand : 1;
|
||||
};
|
||||
|
||||
/// This class provides information about commands that can be used
|
||||
/// in comments.
|
||||
class CommandTraits {
|
||||
public:
|
||||
enum KnownCommandIDs {
|
||||
#define COMMENT_COMMAND(NAME) KCI_##NAME,
|
||||
#include "clang/AST/CommentCommandList.inc"
|
||||
#undef COMMENT_COMMAND
|
||||
KCI_Last
|
||||
};
|
||||
|
||||
CommandTraits(llvm::BumpPtrAllocator &Allocator,
|
||||
const CommentOptions &CommentOptions);
|
||||
|
||||
void registerCommentOptions(const CommentOptions &CommentOptions);
|
||||
|
||||
/// \returns a CommandInfo object for a given command name or
|
||||
/// NULL if no CommandInfo object exists for this command.
|
||||
const CommandInfo *getCommandInfoOrNULL(StringRef Name) const;
|
||||
|
||||
const CommandInfo *getCommandInfo(StringRef Name) const {
|
||||
if (const CommandInfo *Info = getCommandInfoOrNULL(Name))
|
||||
return Info;
|
||||
llvm_unreachable("the command should be known");
|
||||
}
|
||||
|
||||
const CommandInfo *getCommandInfo(unsigned CommandID) const;
|
||||
|
||||
const CommandInfo *registerUnknownCommand(StringRef CommandName);
|
||||
|
||||
const CommandInfo *registerBlockCommand(StringRef CommandName);
|
||||
|
||||
/// \returns a CommandInfo object for a given command name or
|
||||
/// NULL if \c Name is not a builtin command.
|
||||
static const CommandInfo *getBuiltinCommandInfo(StringRef Name);
|
||||
|
||||
/// \returns a CommandInfo object for a given command ID or
|
||||
/// NULL if \c CommandID is not a builtin command.
|
||||
static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID);
|
||||
|
||||
private:
|
||||
CommandTraits(const CommandTraits &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const CommandTraits &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
const CommandInfo *getRegisteredCommandInfo(StringRef Name) const;
|
||||
const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const;
|
||||
|
||||
CommandInfo *createCommandInfoWithName(StringRef CommandName);
|
||||
|
||||
unsigned NextID;
|
||||
|
||||
/// Allocator for CommandInfo objects.
|
||||
llvm::BumpPtrAllocator &Allocator;
|
||||
|
||||
SmallVector<CommandInfo *, 4> RegisteredCommands;
|
||||
};
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
||||
29
thirdparty/clang/include/clang/AST/CommentDiagnostic.h
vendored
Normal file
29
thirdparty/clang/include/clang/AST/CommentDiagnostic.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
//===--- CommentDiagnostic.h - Diagnostics for the AST library --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_COMMENTDIAGNOSTIC_H
|
||||
#define LLVM_CLANG_COMMENTDIAGNOSTIC_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
|
||||
SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
|
||||
#define COMMENTSTART
|
||||
#include "clang/Basic/DiagnosticCommentKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_COMMENT_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
||||
364
thirdparty/clang/include/clang/AST/CommentLexer.h
vendored
Normal file
364
thirdparty/clang/include/clang/AST/CommentLexer.h
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
//===--- CommentLexer.h - Lexer for structured comments ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines lexer for structured comments and supporting token class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_COMMENT_LEXER_H
|
||||
#define LLVM_CLANG_AST_COMMENT_LEXER_H
|
||||
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
class Lexer;
|
||||
class TextTokenRetokenizer;
|
||||
struct CommandInfo;
|
||||
class CommandTraits;
|
||||
|
||||
namespace tok {
|
||||
enum TokenKind {
|
||||
eof,
|
||||
newline,
|
||||
text,
|
||||
unknown_command, // Command that does not have an ID.
|
||||
backslash_command, // Command with an ID, that used backslash marker.
|
||||
at_command, // Command with an ID, that used 'at' marker.
|
||||
verbatim_block_begin,
|
||||
verbatim_block_line,
|
||||
verbatim_block_end,
|
||||
verbatim_line_name,
|
||||
verbatim_line_text,
|
||||
html_start_tag, // <tag
|
||||
html_ident, // attr
|
||||
html_equals, // =
|
||||
html_quoted_string, // "blah\"blah" or 'blah\'blah'
|
||||
html_greater, // >
|
||||
html_slash_greater, // />
|
||||
html_end_tag // </tag
|
||||
};
|
||||
} // end namespace tok
|
||||
|
||||
/// \brief Comment token.
|
||||
class Token {
|
||||
friend class Lexer;
|
||||
friend class TextTokenRetokenizer;
|
||||
|
||||
/// The location of the token.
|
||||
SourceLocation Loc;
|
||||
|
||||
/// The actual kind of the token.
|
||||
tok::TokenKind Kind;
|
||||
|
||||
/// Length of the token spelling in comment. Can be 0 for synthenized
|
||||
/// tokens.
|
||||
unsigned Length;
|
||||
|
||||
/// Contains text value associated with a token.
|
||||
const char *TextPtr;
|
||||
|
||||
/// Integer value associated with a token.
|
||||
///
|
||||
/// If the token is a konwn command, contains command ID and TextPtr is
|
||||
/// unused (command spelling can be found with CommandTraits). Otherwise,
|
||||
/// contains the length of the string that starts at TextPtr.
|
||||
unsigned IntVal;
|
||||
|
||||
public:
|
||||
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
|
||||
void setLocation(SourceLocation SL) { Loc = SL; }
|
||||
|
||||
SourceLocation getEndLocation() const LLVM_READONLY {
|
||||
if (Length == 0 || Length == 1)
|
||||
return Loc;
|
||||
return Loc.getLocWithOffset(Length - 1);
|
||||
}
|
||||
|
||||
tok::TokenKind getKind() const LLVM_READONLY { return Kind; }
|
||||
void setKind(tok::TokenKind K) { Kind = K; }
|
||||
|
||||
bool is(tok::TokenKind K) const LLVM_READONLY { return Kind == K; }
|
||||
bool isNot(tok::TokenKind K) const LLVM_READONLY { return Kind != K; }
|
||||
|
||||
unsigned getLength() const LLVM_READONLY { return Length; }
|
||||
void setLength(unsigned L) { Length = L; }
|
||||
|
||||
StringRef getText() const LLVM_READONLY {
|
||||
assert(is(tok::text));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setText(StringRef Text) {
|
||||
assert(is(tok::text));
|
||||
TextPtr = Text.data();
|
||||
IntVal = Text.size();
|
||||
}
|
||||
|
||||
StringRef getUnknownCommandName() const LLVM_READONLY {
|
||||
assert(is(tok::unknown_command));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setUnknownCommandName(StringRef Name) {
|
||||
assert(is(tok::unknown_command));
|
||||
TextPtr = Name.data();
|
||||
IntVal = Name.size();
|
||||
}
|
||||
|
||||
unsigned getCommandID() const LLVM_READONLY {
|
||||
assert(is(tok::backslash_command) || is(tok::at_command));
|
||||
return IntVal;
|
||||
}
|
||||
|
||||
void setCommandID(unsigned ID) {
|
||||
assert(is(tok::backslash_command) || is(tok::at_command));
|
||||
IntVal = ID;
|
||||
}
|
||||
|
||||
unsigned getVerbatimBlockID() const LLVM_READONLY {
|
||||
assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
|
||||
return IntVal;
|
||||
}
|
||||
|
||||
void setVerbatimBlockID(unsigned ID) {
|
||||
assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
|
||||
IntVal = ID;
|
||||
}
|
||||
|
||||
StringRef getVerbatimBlockText() const LLVM_READONLY {
|
||||
assert(is(tok::verbatim_block_line));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setVerbatimBlockText(StringRef Text) {
|
||||
assert(is(tok::verbatim_block_line));
|
||||
TextPtr = Text.data();
|
||||
IntVal = Text.size();
|
||||
}
|
||||
|
||||
unsigned getVerbatimLineID() const LLVM_READONLY {
|
||||
assert(is(tok::verbatim_line_name));
|
||||
return IntVal;
|
||||
}
|
||||
|
||||
void setVerbatimLineID(unsigned ID) {
|
||||
assert(is(tok::verbatim_line_name));
|
||||
IntVal = ID;
|
||||
}
|
||||
|
||||
StringRef getVerbatimLineText() const LLVM_READONLY {
|
||||
assert(is(tok::verbatim_line_text));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setVerbatimLineText(StringRef Text) {
|
||||
assert(is(tok::verbatim_line_text));
|
||||
TextPtr = Text.data();
|
||||
IntVal = Text.size();
|
||||
}
|
||||
|
||||
StringRef getHTMLTagStartName() const LLVM_READONLY {
|
||||
assert(is(tok::html_start_tag));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setHTMLTagStartName(StringRef Name) {
|
||||
assert(is(tok::html_start_tag));
|
||||
TextPtr = Name.data();
|
||||
IntVal = Name.size();
|
||||
}
|
||||
|
||||
StringRef getHTMLIdent() const LLVM_READONLY {
|
||||
assert(is(tok::html_ident));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setHTMLIdent(StringRef Name) {
|
||||
assert(is(tok::html_ident));
|
||||
TextPtr = Name.data();
|
||||
IntVal = Name.size();
|
||||
}
|
||||
|
||||
StringRef getHTMLQuotedString() const LLVM_READONLY {
|
||||
assert(is(tok::html_quoted_string));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setHTMLQuotedString(StringRef Str) {
|
||||
assert(is(tok::html_quoted_string));
|
||||
TextPtr = Str.data();
|
||||
IntVal = Str.size();
|
||||
}
|
||||
|
||||
StringRef getHTMLTagEndName() const LLVM_READONLY {
|
||||
assert(is(tok::html_end_tag));
|
||||
return StringRef(TextPtr, IntVal);
|
||||
}
|
||||
|
||||
void setHTMLTagEndName(StringRef Name) {
|
||||
assert(is(tok::html_end_tag));
|
||||
TextPtr = Name.data();
|
||||
IntVal = Name.size();
|
||||
}
|
||||
|
||||
void dump(const Lexer &L, const SourceManager &SM) const;
|
||||
};
|
||||
|
||||
/// \brief Comment lexer.
|
||||
class Lexer {
|
||||
private:
|
||||
Lexer(const Lexer &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const Lexer &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
/// Allocator for strings that are semantic values of tokens and have to be
|
||||
/// computed (for example, resolved decimal character references).
|
||||
llvm::BumpPtrAllocator &Allocator;
|
||||
|
||||
const CommandTraits &Traits;
|
||||
|
||||
const char *const BufferStart;
|
||||
const char *const BufferEnd;
|
||||
SourceLocation FileLoc;
|
||||
|
||||
const char *BufferPtr;
|
||||
|
||||
/// One past end pointer for the current comment. For BCPL comments points
|
||||
/// to newline or BufferEnd, for C comments points to star in '*/'.
|
||||
const char *CommentEnd;
|
||||
|
||||
enum LexerCommentState {
|
||||
LCS_BeforeComment,
|
||||
LCS_InsideBCPLComment,
|
||||
LCS_InsideCComment,
|
||||
LCS_BetweenComments
|
||||
};
|
||||
|
||||
/// Low-level lexer state, track if we are inside or outside of comment.
|
||||
LexerCommentState CommentState;
|
||||
|
||||
enum LexerState {
|
||||
/// Lexing normal comment text
|
||||
LS_Normal,
|
||||
|
||||
/// Finished lexing verbatim block beginning command, will lex first body
|
||||
/// line.
|
||||
LS_VerbatimBlockFirstLine,
|
||||
|
||||
/// Lexing verbatim block body line-by-line, skipping line-starting
|
||||
/// decorations.
|
||||
LS_VerbatimBlockBody,
|
||||
|
||||
/// Finished lexing verbatim line beginning command, will lex text (one
|
||||
/// line).
|
||||
LS_VerbatimLineText,
|
||||
|
||||
/// Finished lexing \verbatim <TAG \endverbatim part, lexing tag attributes.
|
||||
LS_HTMLStartTag,
|
||||
|
||||
/// Finished lexing \verbatim </TAG \endverbatim part, lexing '>'.
|
||||
LS_HTMLEndTag
|
||||
};
|
||||
|
||||
/// Current lexing mode.
|
||||
LexerState State;
|
||||
|
||||
/// If State is LS_VerbatimBlock, contains the name of verbatim end
|
||||
/// command, including command marker.
|
||||
SmallString<16> VerbatimBlockEndCommandName;
|
||||
|
||||
/// Given a character reference name (e.g., "lt"), return the character that
|
||||
/// it stands for (e.g., "<").
|
||||
StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
|
||||
|
||||
/// Given a Unicode codepoint as base-10 integer, return the character.
|
||||
StringRef resolveHTMLDecimalCharacterReference(StringRef Name) const;
|
||||
|
||||
/// Given a Unicode codepoint as base-16 integer, return the character.
|
||||
StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
|
||||
|
||||
void formTokenWithChars(Token &Result, const char *TokEnd,
|
||||
tok::TokenKind Kind) {
|
||||
const unsigned TokLen = TokEnd - BufferPtr;
|
||||
Result.setLocation(getSourceLocation(BufferPtr));
|
||||
Result.setKind(Kind);
|
||||
Result.setLength(TokLen);
|
||||
#ifndef NDEBUG
|
||||
Result.TextPtr = "<UNSET>";
|
||||
Result.IntVal = 7;
|
||||
#endif
|
||||
BufferPtr = TokEnd;
|
||||
}
|
||||
|
||||
void formTextToken(Token &Result, const char *TokEnd) {
|
||||
StringRef Text(BufferPtr, TokEnd - BufferPtr);
|
||||
formTokenWithChars(Result, TokEnd, tok::text);
|
||||
Result.setText(Text);
|
||||
}
|
||||
|
||||
SourceLocation getSourceLocation(const char *Loc) const {
|
||||
assert(Loc >= BufferStart && Loc <= BufferEnd &&
|
||||
"Location out of range for this buffer!");
|
||||
|
||||
const unsigned CharNo = Loc - BufferStart;
|
||||
return FileLoc.getLocWithOffset(CharNo);
|
||||
}
|
||||
|
||||
/// Eat string matching regexp \code \s*\* \endcode.
|
||||
void skipLineStartingDecorations();
|
||||
|
||||
/// Lex stuff inside comments. CommentEnd should be set correctly.
|
||||
void lexCommentText(Token &T);
|
||||
|
||||
void setupAndLexVerbatimBlock(Token &T,
|
||||
const char *TextBegin,
|
||||
char Marker, const CommandInfo *Info);
|
||||
|
||||
void lexVerbatimBlockFirstLine(Token &T);
|
||||
|
||||
void lexVerbatimBlockBody(Token &T);
|
||||
|
||||
void setupAndLexVerbatimLine(Token &T, const char *TextBegin,
|
||||
const CommandInfo *Info);
|
||||
|
||||
void lexVerbatimLineText(Token &T);
|
||||
|
||||
void lexHTMLCharacterReference(Token &T);
|
||||
|
||||
void setupAndLexHTMLStartTag(Token &T);
|
||||
|
||||
void lexHTMLStartTag(Token &T);
|
||||
|
||||
void setupAndLexHTMLEndTag(Token &T);
|
||||
|
||||
void lexHTMLEndTag(Token &T);
|
||||
|
||||
public:
|
||||
Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits,
|
||||
SourceLocation FileLoc,
|
||||
const char *BufferStart, const char *BufferEnd);
|
||||
|
||||
void lex(Token &T);
|
||||
|
||||
StringRef getSpelling(const Token &Tok,
|
||||
const SourceManager &SourceMgr,
|
||||
bool *Invalid = NULL) const;
|
||||
};
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
||||
129
thirdparty/clang/include/clang/AST/CommentParser.h
vendored
Normal file
129
thirdparty/clang/include/clang/AST/CommentParser.h
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
//===--- CommentParser.h - Doxygen comment parser ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Doxygen comment parser.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_COMMENT_PARSER_H
|
||||
#define LLVM_CLANG_AST_COMMENT_PARSER_H
|
||||
|
||||
#include "clang/AST/Comment.h"
|
||||
#include "clang/AST/CommentLexer.h"
|
||||
#include "clang/AST/CommentSema.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
|
||||
namespace clang {
|
||||
class SourceManager;
|
||||
|
||||
namespace comments {
|
||||
class CommandTraits;
|
||||
|
||||
/// Doxygen comment parser.
|
||||
class Parser {
|
||||
Parser(const Parser &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const Parser &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
friend class TextTokenRetokenizer;
|
||||
|
||||
Lexer &L;
|
||||
|
||||
Sema &S;
|
||||
|
||||
/// Allocator for anything that goes into AST nodes.
|
||||
llvm::BumpPtrAllocator &Allocator;
|
||||
|
||||
/// Source manager for the comment being parsed.
|
||||
const SourceManager &SourceMgr;
|
||||
|
||||
DiagnosticsEngine &Diags;
|
||||
|
||||
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
|
||||
return Diags.Report(Loc, DiagID);
|
||||
}
|
||||
|
||||
const CommandTraits &Traits;
|
||||
|
||||
/// Current lookahead token. We can safely assume that all tokens are from
|
||||
/// a single source file.
|
||||
Token Tok;
|
||||
|
||||
/// A stack of additional lookahead tokens.
|
||||
SmallVector<Token, 8> MoreLATokens;
|
||||
|
||||
void consumeToken() {
|
||||
if (MoreLATokens.empty())
|
||||
L.lex(Tok);
|
||||
else {
|
||||
Tok = MoreLATokens.back();
|
||||
MoreLATokens.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void putBack(const Token &OldTok) {
|
||||
MoreLATokens.push_back(Tok);
|
||||
Tok = OldTok;
|
||||
}
|
||||
|
||||
void putBack(ArrayRef<Token> Toks) {
|
||||
if (Toks.empty())
|
||||
return;
|
||||
|
||||
MoreLATokens.push_back(Tok);
|
||||
for (const Token *I = &Toks.back(),
|
||||
*B = &Toks.front();
|
||||
I != B; --I) {
|
||||
MoreLATokens.push_back(*I);
|
||||
}
|
||||
|
||||
Tok = Toks[0];
|
||||
}
|
||||
|
||||
bool isTokBlockCommand() {
|
||||
return (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) &&
|
||||
Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand;
|
||||
}
|
||||
|
||||
public:
|
||||
Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
|
||||
const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
|
||||
const CommandTraits &Traits);
|
||||
|
||||
/// Parse arguments for \\param command.
|
||||
void parseParamCommandArgs(ParamCommandComment *PC,
|
||||
TextTokenRetokenizer &Retokenizer);
|
||||
|
||||
/// Parse arguments for \\tparam command.
|
||||
void parseTParamCommandArgs(TParamCommandComment *TPC,
|
||||
TextTokenRetokenizer &Retokenizer);
|
||||
|
||||
void parseBlockCommandArgs(BlockCommandComment *BC,
|
||||
TextTokenRetokenizer &Retokenizer,
|
||||
unsigned NumArgs);
|
||||
|
||||
BlockCommandComment *parseBlockCommand();
|
||||
InlineCommandComment *parseInlineCommand();
|
||||
|
||||
HTMLStartTagComment *parseHTMLStartTag();
|
||||
HTMLEndTagComment *parseHTMLEndTag();
|
||||
|
||||
BlockContentComment *parseParagraphOrBlockCommand();
|
||||
|
||||
VerbatimBlockComment *parseVerbatimBlock();
|
||||
VerbatimLineComment *parseVerbatimLine();
|
||||
BlockContentComment *parseBlockContent();
|
||||
FullComment *parseFullComment();
|
||||
};
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
||||
255
thirdparty/clang/include/clang/AST/CommentSema.h
vendored
Normal file
255
thirdparty/clang/include/clang/AST/CommentSema.h
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
//===--- CommentSema.h - Doxygen comment semantic analysis ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the semantic analysis class for Doxygen comments.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_COMMENT_SEMA_H
|
||||
#define LLVM_CLANG_AST_COMMENT_SEMA_H
|
||||
|
||||
#include "clang/AST/Comment.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
|
||||
namespace clang {
|
||||
class Decl;
|
||||
class SourceMgr;
|
||||
class Preprocessor;
|
||||
|
||||
namespace comments {
|
||||
class CommandTraits;
|
||||
|
||||
class Sema {
|
||||
Sema(const Sema &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const Sema &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
/// Allocator for AST nodes.
|
||||
llvm::BumpPtrAllocator &Allocator;
|
||||
|
||||
/// Source manager for the comment being parsed.
|
||||
const SourceManager &SourceMgr;
|
||||
|
||||
DiagnosticsEngine &Diags;
|
||||
|
||||
CommandTraits &Traits;
|
||||
|
||||
const Preprocessor *PP;
|
||||
|
||||
/// Information about the declaration this comment is attached to.
|
||||
DeclInfo *ThisDeclInfo;
|
||||
|
||||
/// Comment AST nodes that correspond to parameter names in
|
||||
/// \c TemplateParameters.
|
||||
///
|
||||
/// Contains a valid value if \c DeclInfo->IsFilled is true.
|
||||
llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
|
||||
|
||||
/// AST node for the \\brief command and its aliases.
|
||||
const BlockCommandComment *BriefCommand;
|
||||
|
||||
/// AST node for the \\returns command and its aliases.
|
||||
const BlockCommandComment *ReturnsCommand;
|
||||
|
||||
/// AST node for the \\headerfile command.
|
||||
const BlockCommandComment *HeaderfileCommand;
|
||||
|
||||
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
|
||||
return Diags.Report(Loc, DiagID);
|
||||
}
|
||||
|
||||
/// A stack of HTML tags that are currently open (not matched with closing
|
||||
/// tags).
|
||||
SmallVector<HTMLStartTagComment *, 8> HTMLOpenTags;
|
||||
|
||||
public:
|
||||
Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
|
||||
DiagnosticsEngine &Diags, CommandTraits &Traits,
|
||||
const Preprocessor *PP);
|
||||
|
||||
void setDecl(const Decl *D);
|
||||
|
||||
/// Returns a copy of array, owned by Sema's allocator.
|
||||
template<typename T>
|
||||
ArrayRef<T> copyArray(ArrayRef<T> Source) {
|
||||
size_t Size = Source.size();
|
||||
if (Size != 0) {
|
||||
T *Mem = Allocator.Allocate<T>(Size);
|
||||
std::uninitialized_copy(Source.begin(), Source.end(), Mem);
|
||||
return llvm::makeArrayRef(Mem, Size);
|
||||
} else
|
||||
return llvm::makeArrayRef(static_cast<T *>(NULL), 0);
|
||||
}
|
||||
|
||||
ParagraphComment *actOnParagraphComment(
|
||||
ArrayRef<InlineContentComment *> Content);
|
||||
|
||||
BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
|
||||
SourceLocation LocEnd,
|
||||
unsigned CommandID,
|
||||
CommandMarkerKind CommandMarker);
|
||||
|
||||
void actOnBlockCommandArgs(BlockCommandComment *Command,
|
||||
ArrayRef<BlockCommandComment::Argument> Args);
|
||||
|
||||
void actOnBlockCommandFinish(BlockCommandComment *Command,
|
||||
ParagraphComment *Paragraph);
|
||||
|
||||
ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
|
||||
SourceLocation LocEnd,
|
||||
unsigned CommandID,
|
||||
CommandMarkerKind CommandMarker);
|
||||
|
||||
void actOnParamCommandDirectionArg(ParamCommandComment *Command,
|
||||
SourceLocation ArgLocBegin,
|
||||
SourceLocation ArgLocEnd,
|
||||
StringRef Arg);
|
||||
|
||||
void actOnParamCommandParamNameArg(ParamCommandComment *Command,
|
||||
SourceLocation ArgLocBegin,
|
||||
SourceLocation ArgLocEnd,
|
||||
StringRef Arg);
|
||||
|
||||
void actOnParamCommandFinish(ParamCommandComment *Command,
|
||||
ParagraphComment *Paragraph);
|
||||
|
||||
TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
|
||||
SourceLocation LocEnd,
|
||||
unsigned CommandID,
|
||||
CommandMarkerKind CommandMarker);
|
||||
|
||||
void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
|
||||
SourceLocation ArgLocBegin,
|
||||
SourceLocation ArgLocEnd,
|
||||
StringRef Arg);
|
||||
|
||||
void actOnTParamCommandFinish(TParamCommandComment *Command,
|
||||
ParagraphComment *Paragraph);
|
||||
|
||||
InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
|
||||
SourceLocation CommandLocEnd,
|
||||
unsigned CommandID);
|
||||
|
||||
InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
|
||||
SourceLocation CommandLocEnd,
|
||||
unsigned CommandID,
|
||||
SourceLocation ArgLocBegin,
|
||||
SourceLocation ArgLocEnd,
|
||||
StringRef Arg);
|
||||
|
||||
InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
|
||||
SourceLocation LocEnd,
|
||||
StringRef CommandName);
|
||||
|
||||
InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
|
||||
SourceLocation LocEnd,
|
||||
unsigned CommandID);
|
||||
|
||||
TextComment *actOnText(SourceLocation LocBegin,
|
||||
SourceLocation LocEnd,
|
||||
StringRef Text);
|
||||
|
||||
VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
|
||||
unsigned CommandID);
|
||||
|
||||
VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
|
||||
StringRef Text);
|
||||
|
||||
void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
|
||||
SourceLocation CloseNameLocBegin,
|
||||
StringRef CloseName,
|
||||
ArrayRef<VerbatimBlockLineComment *> Lines);
|
||||
|
||||
VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
|
||||
unsigned CommandID,
|
||||
SourceLocation TextBegin,
|
||||
StringRef Text);
|
||||
|
||||
HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
|
||||
StringRef TagName);
|
||||
|
||||
void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
|
||||
ArrayRef<HTMLStartTagComment::Attribute> Attrs,
|
||||
SourceLocation GreaterLoc,
|
||||
bool IsSelfClosing);
|
||||
|
||||
HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
|
||||
SourceLocation LocEnd,
|
||||
StringRef TagName);
|
||||
|
||||
FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
|
||||
|
||||
void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
|
||||
|
||||
void checkReturnsCommand(const BlockCommandComment *Command);
|
||||
|
||||
/// Emit diagnostics about duplicate block commands that should be
|
||||
/// used only once per comment, e.g., \\brief and \\returns.
|
||||
void checkBlockCommandDuplicate(const BlockCommandComment *Command);
|
||||
|
||||
void checkDeprecatedCommand(const BlockCommandComment *Comment);
|
||||
|
||||
void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
|
||||
|
||||
void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
|
||||
|
||||
void checkContainerDecl(const BlockCommandComment *Comment);
|
||||
|
||||
/// Resolve parameter names to parameter indexes in function declaration.
|
||||
/// Emit diagnostics about unknown parametrs.
|
||||
void resolveParamCommandIndexes(const FullComment *FC);
|
||||
|
||||
bool isFunctionDecl();
|
||||
bool isAnyFunctionDecl();
|
||||
bool isFunctionPointerVarDecl();
|
||||
bool isObjCMethodDecl();
|
||||
bool isObjCPropertyDecl();
|
||||
bool isTemplateOrSpecialization();
|
||||
bool isRecordLikeDecl();
|
||||
bool isClassOrStructDecl();
|
||||
bool isUnionDecl();
|
||||
bool isObjCInterfaceDecl();
|
||||
bool isObjCProtocolDecl();
|
||||
|
||||
ArrayRef<const ParmVarDecl *> getParamVars();
|
||||
|
||||
/// Extract all important semantic information from
|
||||
/// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
|
||||
void inspectThisDecl();
|
||||
|
||||
/// Returns index of a function parameter with a given name.
|
||||
unsigned resolveParmVarReference(StringRef Name,
|
||||
ArrayRef<const ParmVarDecl *> ParamVars);
|
||||
|
||||
/// Returns index of a function parameter with the name closest to a given
|
||||
/// typo.
|
||||
unsigned correctTypoInParmVarReference(StringRef Typo,
|
||||
ArrayRef<const ParmVarDecl *> ParamVars);
|
||||
|
||||
bool resolveTParamReference(StringRef Name,
|
||||
const TemplateParameterList *TemplateParameters,
|
||||
SmallVectorImpl<unsigned> *Position);
|
||||
|
||||
StringRef correctTypoInTParamReference(
|
||||
StringRef Typo,
|
||||
const TemplateParameterList *TemplateParameters);
|
||||
|
||||
InlineCommandComment::RenderKind
|
||||
getInlineCommandRenderKind(StringRef Name) const;
|
||||
};
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
||||
70
thirdparty/clang/include/clang/AST/CommentVisitor.h
vendored
Normal file
70
thirdparty/clang/include/clang/AST/CommentVisitor.h
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_COMMENTVISITOR_H
|
||||
#define LLVM_CLANG_AST_COMMENTVISITOR_H
|
||||
|
||||
#include "clang/AST/Comment.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
template <typename T> struct make_ptr { typedef T *type; };
|
||||
template <typename T> struct make_const_ptr { typedef const T *type; };
|
||||
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
class CommentVisitorBase {
|
||||
public:
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(NAME, CLASS) \
|
||||
return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
|
||||
|
||||
RetTy visit(PTR(Comment) C) {
|
||||
if (!C)
|
||||
return RetTy();
|
||||
|
||||
switch (C->getCommentKind()) {
|
||||
default: llvm_unreachable("Unknown comment kind!");
|
||||
#define ABSTRACT_COMMENT(COMMENT)
|
||||
#define COMMENT(CLASS, PARENT) \
|
||||
case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
|
||||
#include "clang/AST/CommentNodes.inc"
|
||||
#undef ABSTRACT_COMMENT
|
||||
#undef COMMENT
|
||||
}
|
||||
}
|
||||
|
||||
// If the derived class does not implement a certain Visit* method, fall back
|
||||
// on Visit* method for the superclass.
|
||||
#define ABSTRACT_COMMENT(COMMENT) COMMENT
|
||||
#define COMMENT(CLASS, PARENT) \
|
||||
RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
|
||||
#include "clang/AST/CommentNodes.inc"
|
||||
#undef ABSTRACT_COMMENT
|
||||
#undef COMMENT
|
||||
|
||||
RetTy visitComment(PTR(Comment) C) { return RetTy(); }
|
||||
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class CommentVisitor :
|
||||
public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
|
||||
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class ConstCommentVisitor :
|
||||
public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
3337
thirdparty/clang/include/clang/AST/Decl.h
vendored
Normal file
3337
thirdparty/clang/include/clang/AST/Decl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
73
thirdparty/clang/include/clang/AST/DeclAccessPair.h
vendored
Normal file
73
thirdparty/clang/include/clang/AST/DeclAccessPair.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the DeclAccessPair class, which provides an
|
||||
// efficient representation of a pair of a NamedDecl* and an
|
||||
// AccessSpecifier. Generally the access specifier gives the
|
||||
// natural access of a declaration when named in a class, as
|
||||
// defined in C++ [class.access.base]p1.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
|
||||
#define LLVM_CLANG_AST_DECLACCESSPAIR_H
|
||||
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class NamedDecl;
|
||||
|
||||
/// A POD class for pairing a NamedDecl* with an access specifier.
|
||||
/// Can be put into unions.
|
||||
class DeclAccessPair {
|
||||
NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
|
||||
|
||||
enum { Mask = 0x3 };
|
||||
|
||||
public:
|
||||
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
|
||||
DeclAccessPair p;
|
||||
p.set(D, AS);
|
||||
return p;
|
||||
}
|
||||
|
||||
NamedDecl *getDecl() const {
|
||||
return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
|
||||
}
|
||||
AccessSpecifier getAccess() const {
|
||||
return AccessSpecifier(Mask & (uintptr_t) Ptr);
|
||||
}
|
||||
|
||||
void setDecl(NamedDecl *D) {
|
||||
set(D, getAccess());
|
||||
}
|
||||
void setAccess(AccessSpecifier AS) {
|
||||
set(getDecl(), AS);
|
||||
}
|
||||
void set(NamedDecl *D, AccessSpecifier AS) {
|
||||
Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
|
||||
reinterpret_cast<uintptr_t>(D));
|
||||
}
|
||||
|
||||
operator NamedDecl*() const { return getDecl(); }
|
||||
NamedDecl *operator->() const { return getDecl(); }
|
||||
};
|
||||
}
|
||||
|
||||
// Take a moment to tell SmallVector that DeclAccessPair is POD.
|
||||
namespace llvm {
|
||||
template<typename> struct isPodLike;
|
||||
template<> struct isPodLike<clang::DeclAccessPair> {
|
||||
static const bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
1661
thirdparty/clang/include/clang/AST/DeclBase.h
vendored
Normal file
1661
thirdparty/clang/include/clang/AST/DeclBase.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3039
thirdparty/clang/include/clang/AST/DeclCXX.h
vendored
Normal file
3039
thirdparty/clang/include/clang/AST/DeclCXX.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
239
thirdparty/clang/include/clang/AST/DeclContextInternals.h
vendored
Normal file
239
thirdparty/clang/include/clang/AST/DeclContextInternals.h
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the data structures used in the implementation
|
||||
// of DeclContext.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
|
||||
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class DependentDiagnostic;
|
||||
|
||||
/// StoredDeclsList - This is an array of decls optimized a common case of only
|
||||
/// containing one entry.
|
||||
struct StoredDeclsList {
|
||||
|
||||
/// DeclsTy - When in vector form, this is what the Data pointer points to.
|
||||
typedef SmallVector<NamedDecl *, 4> DeclsTy;
|
||||
|
||||
/// \brief The stored data, which will be either a pointer to a NamedDecl,
|
||||
/// or a pointer to a vector.
|
||||
llvm::PointerUnion<NamedDecl *, DeclsTy *> Data;
|
||||
|
||||
public:
|
||||
StoredDeclsList() {}
|
||||
|
||||
StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
|
||||
if (DeclsTy *RHSVec = RHS.getAsVector())
|
||||
Data = new DeclsTy(*RHSVec);
|
||||
}
|
||||
|
||||
~StoredDeclsList() {
|
||||
// If this is a vector-form, free the vector.
|
||||
if (DeclsTy *Vector = getAsVector())
|
||||
delete Vector;
|
||||
}
|
||||
|
||||
StoredDeclsList &operator=(const StoredDeclsList &RHS) {
|
||||
if (DeclsTy *Vector = getAsVector())
|
||||
delete Vector;
|
||||
Data = RHS.Data;
|
||||
if (DeclsTy *RHSVec = RHS.getAsVector())
|
||||
Data = new DeclsTy(*RHSVec);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isNull() const { return Data.isNull(); }
|
||||
|
||||
NamedDecl *getAsDecl() const {
|
||||
return Data.dyn_cast<NamedDecl *>();
|
||||
}
|
||||
|
||||
DeclsTy *getAsVector() const {
|
||||
return Data.dyn_cast<DeclsTy *>();
|
||||
}
|
||||
|
||||
void setOnlyValue(NamedDecl *ND) {
|
||||
assert(!getAsVector() && "Not inline");
|
||||
Data = ND;
|
||||
// Make sure that Data is a plain NamedDecl* so we can use its address
|
||||
// at getLookupResult.
|
||||
assert(*(NamedDecl **)&Data == ND &&
|
||||
"PointerUnion mangles the NamedDecl pointer!");
|
||||
}
|
||||
|
||||
void remove(NamedDecl *D) {
|
||||
assert(!isNull() && "removing from empty list");
|
||||
if (NamedDecl *Singleton = getAsDecl()) {
|
||||
assert(Singleton == D && "list is different singleton");
|
||||
(void)Singleton;
|
||||
Data = (NamedDecl *)0;
|
||||
return;
|
||||
}
|
||||
|
||||
DeclsTy &Vec = *getAsVector();
|
||||
DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
|
||||
assert(I != Vec.end() && "list does not contain decl");
|
||||
Vec.erase(I);
|
||||
|
||||
assert(std::find(Vec.begin(), Vec.end(), D)
|
||||
== Vec.end() && "list still contains decl");
|
||||
}
|
||||
|
||||
/// \brief Remove any declarations which were imported from an external
|
||||
/// AST source.
|
||||
void removeExternalDecls() {
|
||||
if (isNull()) {
|
||||
// Nothing to do.
|
||||
} else if (NamedDecl *Singleton = getAsDecl()) {
|
||||
if (Singleton->isFromASTFile())
|
||||
*this = StoredDeclsList();
|
||||
} else {
|
||||
DeclsTy &Vec = *getAsVector();
|
||||
Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
|
||||
std::mem_fun(&Decl::isFromASTFile)),
|
||||
Vec.end());
|
||||
}
|
||||
}
|
||||
|
||||
/// getLookupResult - Return an array of all the decls that this list
|
||||
/// represents.
|
||||
DeclContext::lookup_result getLookupResult() {
|
||||
if (isNull())
|
||||
return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
|
||||
DeclContext::lookup_iterator(0));
|
||||
|
||||
// If we have a single NamedDecl, return it.
|
||||
if (getAsDecl()) {
|
||||
assert(!isNull() && "Empty list isn't allowed");
|
||||
|
||||
// Data is a raw pointer to a NamedDecl*, return it.
|
||||
void *Ptr = &Data;
|
||||
return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1);
|
||||
}
|
||||
|
||||
assert(getAsVector() && "Must have a vector at this point");
|
||||
DeclsTy &Vector = *getAsVector();
|
||||
|
||||
// Otherwise, we have a range result.
|
||||
return DeclContext::lookup_result(Vector.begin(), Vector.end());
|
||||
}
|
||||
|
||||
/// HandleRedeclaration - If this is a redeclaration of an existing decl,
|
||||
/// replace the old one with D and return true. Otherwise return false.
|
||||
bool HandleRedeclaration(NamedDecl *D) {
|
||||
// Most decls only have one entry in their list, special case it.
|
||||
if (NamedDecl *OldD = getAsDecl()) {
|
||||
if (!D->declarationReplaces(OldD))
|
||||
return false;
|
||||
setOnlyValue(D);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine if this declaration is actually a redeclaration.
|
||||
DeclsTy &Vec = *getAsVector();
|
||||
for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
|
||||
OD != ODEnd; ++OD) {
|
||||
NamedDecl *OldD = *OD;
|
||||
if (D->declarationReplaces(OldD)) {
|
||||
*OD = D;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// AddSubsequentDecl - This is called on the second and later decl when it is
|
||||
/// not a redeclaration to merge it into the appropriate place in our list.
|
||||
///
|
||||
void AddSubsequentDecl(NamedDecl *D) {
|
||||
// If this is the second decl added to the list, convert this to vector
|
||||
// form.
|
||||
if (NamedDecl *OldD = getAsDecl()) {
|
||||
DeclsTy *VT = new DeclsTy();
|
||||
VT->push_back(OldD);
|
||||
Data = VT;
|
||||
}
|
||||
|
||||
DeclsTy &Vec = *getAsVector();
|
||||
|
||||
// Using directives end up in a special entry which contains only
|
||||
// other using directives, so all this logic is wasted for them.
|
||||
// But avoiding the logic wastes time in the far-more-common case
|
||||
// that we're *not* adding a new using directive.
|
||||
|
||||
// Tag declarations always go at the end of the list so that an
|
||||
// iterator which points at the first tag will start a span of
|
||||
// decls that only contains tags.
|
||||
if (D->hasTagIdentifierNamespace())
|
||||
Vec.push_back(D);
|
||||
|
||||
// Resolved using declarations go at the front of the list so that
|
||||
// they won't show up in other lookup results. Unresolved using
|
||||
// declarations (which are always in IDNS_Using | IDNS_Ordinary)
|
||||
// follow that so that the using declarations will be contiguous.
|
||||
else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
|
||||
DeclsTy::iterator I = Vec.begin();
|
||||
if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
|
||||
while (I != Vec.end() &&
|
||||
(*I)->getIdentifierNamespace() == Decl::IDNS_Using)
|
||||
++I;
|
||||
}
|
||||
Vec.insert(I, D);
|
||||
|
||||
// All other declarations go at the end of the list, but before any
|
||||
// tag declarations. But we can be clever about tag declarations
|
||||
// because there can only ever be one in a scope.
|
||||
} else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) {
|
||||
NamedDecl *TagD = Vec.back();
|
||||
Vec.back() = D;
|
||||
Vec.push_back(TagD);
|
||||
} else
|
||||
Vec.push_back(D);
|
||||
}
|
||||
};
|
||||
|
||||
class StoredDeclsMap
|
||||
: public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
|
||||
|
||||
public:
|
||||
static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
|
||||
|
||||
private:
|
||||
friend class ASTContext; // walks the chain deleting these
|
||||
friend class DeclContext;
|
||||
llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
|
||||
};
|
||||
|
||||
class DependentStoredDeclsMap : public StoredDeclsMap {
|
||||
public:
|
||||
DependentStoredDeclsMap() : FirstDiagnostic(0) {}
|
||||
|
||||
private:
|
||||
friend class DependentDiagnostic;
|
||||
friend class DeclContext; // iterates over diagnostics
|
||||
|
||||
DependentDiagnostic *FirstDiagnostic;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
238
thirdparty/clang/include/clang/AST/DeclFriend.h
vendored
Normal file
238
thirdparty/clang/include/clang/AST/DeclFriend.h
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the section of the AST representing C++ friend
|
||||
// declarations.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLFRIEND_H
|
||||
#define LLVM_CLANG_AST_DECLFRIEND_H
|
||||
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// FriendDecl - Represents the declaration of a friend entity,
|
||||
/// which can be a function, a type, or a templated function or type.
|
||||
// For example:
|
||||
///
|
||||
/// @code
|
||||
/// template <typename T> class A {
|
||||
/// friend int foo(T);
|
||||
/// friend class B;
|
||||
/// friend T; // only in C++0x
|
||||
/// template <typename U> friend class C;
|
||||
/// template <typename U> friend A& operator+=(A&, const U&) { ... }
|
||||
/// };
|
||||
/// @endcode
|
||||
///
|
||||
/// The semantic context of a friend decl is its declaring class.
|
||||
class FriendDecl : public Decl {
|
||||
virtual void anchor();
|
||||
public:
|
||||
typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
|
||||
|
||||
private:
|
||||
// The declaration that's a friend of this class.
|
||||
FriendUnion Friend;
|
||||
|
||||
// A pointer to the next friend in the sequence.
|
||||
LazyDeclPtr NextFriend;
|
||||
|
||||
// Location of the 'friend' specifier.
|
||||
SourceLocation FriendLoc;
|
||||
|
||||
/// True if this 'friend' declaration is unsupported. Eventually we
|
||||
/// will support every possible friend declaration, but for now we
|
||||
/// silently ignore some and set this flag to authorize all access.
|
||||
bool UnsupportedFriend : 1;
|
||||
|
||||
// The number of "outer" template parameter lists in non-templatic
|
||||
// (currently unsupported) friend type declarations, such as
|
||||
// template <class T> friend class A<T>::B;
|
||||
unsigned NumTPLists : 31;
|
||||
|
||||
// The tail-allocated friend type template parameter lists (if any).
|
||||
TemplateParameterList* const *getTPLists() const {
|
||||
return reinterpret_cast<TemplateParameterList* const *>(this + 1);
|
||||
}
|
||||
TemplateParameterList **getTPLists() {
|
||||
return reinterpret_cast<TemplateParameterList**>(this + 1);
|
||||
}
|
||||
|
||||
friend class CXXRecordDecl::friend_iterator;
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
|
||||
SourceLocation FriendL,
|
||||
ArrayRef<TemplateParameterList*> FriendTypeTPLists)
|
||||
: Decl(Decl::Friend, DC, L),
|
||||
Friend(Friend),
|
||||
NextFriend(),
|
||||
FriendLoc(FriendL),
|
||||
UnsupportedFriend(false),
|
||||
NumTPLists(FriendTypeTPLists.size()) {
|
||||
for (unsigned i = 0; i < NumTPLists; ++i)
|
||||
getTPLists()[i] = FriendTypeTPLists[i];
|
||||
}
|
||||
|
||||
FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
|
||||
: Decl(Decl::Friend, Empty), NextFriend(),
|
||||
NumTPLists(NumFriendTypeTPLists) { }
|
||||
|
||||
FriendDecl *getNextFriend() {
|
||||
if (!NextFriend.isOffset())
|
||||
return cast_or_null<FriendDecl>(NextFriend.get(0));
|
||||
return getNextFriendSlowCase();
|
||||
}
|
||||
FriendDecl *getNextFriendSlowCase();
|
||||
|
||||
public:
|
||||
static FriendDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, FriendUnion Friend_,
|
||||
SourceLocation FriendL,
|
||||
ArrayRef<TemplateParameterList*> FriendTypeTPLists
|
||||
= ArrayRef<TemplateParameterList*>());
|
||||
static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
|
||||
unsigned FriendTypeNumTPLists);
|
||||
|
||||
/// If this friend declaration names an (untemplated but possibly
|
||||
/// dependent) type, return the type; otherwise return null. This
|
||||
/// is used for elaborated-type-specifiers and, in C++0x, for
|
||||
/// arbitrary friend type declarations.
|
||||
TypeSourceInfo *getFriendType() const {
|
||||
return Friend.dyn_cast<TypeSourceInfo*>();
|
||||
}
|
||||
unsigned getFriendTypeNumTemplateParameterLists() const {
|
||||
return NumTPLists;
|
||||
}
|
||||
TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
|
||||
assert(N < NumTPLists);
|
||||
return getTPLists()[N];
|
||||
}
|
||||
|
||||
/// If this friend declaration doesn't name a type, return the inner
|
||||
/// declaration.
|
||||
NamedDecl *getFriendDecl() const {
|
||||
return Friend.dyn_cast<NamedDecl*>();
|
||||
}
|
||||
|
||||
/// Retrieves the location of the 'friend' keyword.
|
||||
SourceLocation getFriendLoc() const {
|
||||
return FriendLoc;
|
||||
}
|
||||
|
||||
/// Retrieves the source range for the friend declaration.
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
if (NamedDecl *ND = getFriendDecl()) {
|
||||
if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
|
||||
return FTD->getSourceRange();
|
||||
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
|
||||
if (DD->getOuterLocStart() != DD->getInnerLocStart())
|
||||
return DD->getSourceRange();
|
||||
}
|
||||
return SourceRange(getFriendLoc(), ND->getLocEnd());
|
||||
}
|
||||
else if (TypeSourceInfo *TInfo = getFriendType()) {
|
||||
SourceLocation StartL = (NumTPLists == 0)
|
||||
? getFriendLoc()
|
||||
: getTPLists()[0]->getTemplateLoc();
|
||||
return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
|
||||
}
|
||||
else
|
||||
return SourceRange(getFriendLoc(), getLocation());
|
||||
}
|
||||
|
||||
/// Determines if this friend kind is unsupported.
|
||||
bool isUnsupportedFriend() const {
|
||||
return UnsupportedFriend;
|
||||
}
|
||||
void setUnsupportedFriend(bool Unsupported) {
|
||||
UnsupportedFriend = Unsupported;
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == Decl::Friend; }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
};
|
||||
|
||||
/// An iterator over the friend declarations of a class.
|
||||
class CXXRecordDecl::friend_iterator {
|
||||
FriendDecl *Ptr;
|
||||
|
||||
friend class CXXRecordDecl;
|
||||
explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
|
||||
public:
|
||||
friend_iterator() {}
|
||||
|
||||
typedef FriendDecl *value_type;
|
||||
typedef FriendDecl *reference;
|
||||
typedef FriendDecl *pointer;
|
||||
typedef int difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
reference operator*() const { return Ptr; }
|
||||
|
||||
friend_iterator &operator++() {
|
||||
assert(Ptr && "attempt to increment past end of friend list");
|
||||
Ptr = Ptr->getNextFriend();
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend_iterator operator++(int) {
|
||||
friend_iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const friend_iterator &Other) const {
|
||||
return Ptr == Other.Ptr;
|
||||
}
|
||||
|
||||
bool operator!=(const friend_iterator &Other) const {
|
||||
return Ptr != Other.Ptr;
|
||||
}
|
||||
|
||||
friend_iterator &operator+=(difference_type N) {
|
||||
assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator");
|
||||
while (N--)
|
||||
++*this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend_iterator operator+(difference_type N) const {
|
||||
friend_iterator tmp = *this;
|
||||
tmp += N;
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
|
||||
return friend_iterator(data().FirstFriend);
|
||||
}
|
||||
|
||||
inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
|
||||
return friend_iterator(0);
|
||||
}
|
||||
|
||||
inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
|
||||
assert(FD->NextFriend == 0 && "friend already has next friend?");
|
||||
FD->NextFriend = data().FirstFriend;
|
||||
data().FirstFriend = FD;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
155
thirdparty/clang/include/clang/AST/DeclGroup.h
vendored
Normal file
155
thirdparty/clang/include/clang/AST/DeclGroup.h
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLGROUP_H
|
||||
#define LLVM_CLANG_AST_DECLGROUP_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class Decl;
|
||||
class DeclGroup;
|
||||
class DeclGroupIterator;
|
||||
|
||||
class DeclGroup {
|
||||
// FIXME: Include a TypeSpecifier object.
|
||||
union {
|
||||
unsigned NumDecls;
|
||||
|
||||
Decl *Aligner;
|
||||
};
|
||||
|
||||
private:
|
||||
DeclGroup() : NumDecls(0) {}
|
||||
DeclGroup(unsigned numdecls, Decl** decls);
|
||||
|
||||
public:
|
||||
static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
|
||||
|
||||
unsigned size() const { return NumDecls; }
|
||||
|
||||
Decl*& operator[](unsigned i) {
|
||||
assert (i < NumDecls && "Out-of-bounds access.");
|
||||
return ((Decl**) (this+1))[i];
|
||||
}
|
||||
|
||||
Decl* const& operator[](unsigned i) const {
|
||||
assert (i < NumDecls && "Out-of-bounds access.");
|
||||
return ((Decl* const*) (this+1))[i];
|
||||
}
|
||||
};
|
||||
|
||||
class DeclGroupRef {
|
||||
// Note this is not a PointerIntPair because we need the address of the
|
||||
// non-group case to be valid as a Decl** for iteration.
|
||||
enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
|
||||
Decl* D;
|
||||
|
||||
Kind getKind() const {
|
||||
return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
|
||||
}
|
||||
|
||||
public:
|
||||
DeclGroupRef() : D(0) {}
|
||||
|
||||
explicit DeclGroupRef(Decl* d) : D(d) {}
|
||||
explicit DeclGroupRef(DeclGroup* dg)
|
||||
: D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
|
||||
|
||||
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
|
||||
if (NumDecls == 0)
|
||||
return DeclGroupRef();
|
||||
if (NumDecls == 1)
|
||||
return DeclGroupRef(Decls[0]);
|
||||
return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
|
||||
}
|
||||
|
||||
typedef Decl** iterator;
|
||||
typedef Decl* const * const_iterator;
|
||||
|
||||
bool isNull() const { return D == 0; }
|
||||
bool isSingleDecl() const { return getKind() == SingleDeclKind; }
|
||||
bool isDeclGroup() const { return getKind() == DeclGroupKind; }
|
||||
|
||||
Decl *getSingleDecl() {
|
||||
assert(isSingleDecl() && "Isn't a declgroup");
|
||||
return D;
|
||||
}
|
||||
const Decl *getSingleDecl() const {
|
||||
return const_cast<DeclGroupRef*>(this)->getSingleDecl();
|
||||
}
|
||||
|
||||
DeclGroup &getDeclGroup() {
|
||||
assert(isDeclGroup() && "Isn't a declgroup");
|
||||
return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
|
||||
}
|
||||
const DeclGroup &getDeclGroup() const {
|
||||
return const_cast<DeclGroupRef*>(this)->getDeclGroup();
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
if (isSingleDecl())
|
||||
return D ? &D : 0;
|
||||
return &getDeclGroup()[0];
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
if (isSingleDecl())
|
||||
return D ? &D+1 : 0;
|
||||
DeclGroup &G = getDeclGroup();
|
||||
return &G[0] + G.size();
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
if (isSingleDecl())
|
||||
return D ? &D : 0;
|
||||
return &getDeclGroup()[0];
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
if (isSingleDecl())
|
||||
return D ? &D+1 : 0;
|
||||
const DeclGroup &G = getDeclGroup();
|
||||
return &G[0] + G.size();
|
||||
}
|
||||
|
||||
void *getAsOpaquePtr() const { return D; }
|
||||
static DeclGroupRef getFromOpaquePtr(void *Ptr) {
|
||||
DeclGroupRef X;
|
||||
X.D = static_cast<Decl*>(Ptr);
|
||||
return X;
|
||||
}
|
||||
};
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
namespace llvm {
|
||||
// DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
|
||||
template <typename T>
|
||||
class PointerLikeTypeTraits;
|
||||
template <>
|
||||
class PointerLikeTypeTraits<clang::DeclGroupRef> {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
|
||||
return P.getAsOpaquePtr();
|
||||
}
|
||||
static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
|
||||
return clang::DeclGroupRef::getFromOpaquePtr(P);
|
||||
}
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
}
|
||||
#endif
|
||||
89
thirdparty/clang/include/clang/AST/DeclLookups.h
vendored
Normal file
89
thirdparty/clang/include/clang/AST/DeclLookups.h
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
//===-- DeclLookups.h - Low-level interface to all names in a DC-*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines DeclContext::all_lookups_iterator.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
|
||||
#define LLVM_CLANG_AST_DECLLOOKUPS_H
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclContextInternals.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// all_lookups_iterator - An iterator that provides a view over the results
|
||||
/// of looking up every possible name.
|
||||
class DeclContext::all_lookups_iterator {
|
||||
StoredDeclsMap::iterator It, End;
|
||||
public:
|
||||
typedef lookup_result value_type;
|
||||
typedef lookup_result reference;
|
||||
typedef lookup_result pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
all_lookups_iterator() {}
|
||||
all_lookups_iterator(StoredDeclsMap::iterator It,
|
||||
StoredDeclsMap::iterator End)
|
||||
: It(It), End(End) {}
|
||||
|
||||
reference operator*() const { return It->second.getLookupResult(); }
|
||||
pointer operator->() const { return It->second.getLookupResult(); }
|
||||
|
||||
all_lookups_iterator& operator++() {
|
||||
// Filter out using directives. They don't belong as results from name
|
||||
// lookup anyways, except as an implementation detail. Users of the API
|
||||
// should not expect to get them (or worse, rely on it).
|
||||
do {
|
||||
++It;
|
||||
} while (It != End &&
|
||||
It->first == DeclarationName::getUsingDirectiveName());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
all_lookups_iterator operator++(int) {
|
||||
all_lookups_iterator tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
|
||||
return x.It == y.It;
|
||||
}
|
||||
friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
|
||||
return x.It != y.It;
|
||||
}
|
||||
};
|
||||
|
||||
DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
|
||||
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
|
||||
if (Primary->hasExternalVisibleStorage())
|
||||
getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
|
||||
if (StoredDeclsMap *Map = Primary->buildLookup())
|
||||
return all_lookups_iterator(Map->begin(), Map->end());
|
||||
return all_lookups_iterator();
|
||||
}
|
||||
|
||||
DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
|
||||
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
|
||||
if (Primary->hasExternalVisibleStorage())
|
||||
getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
|
||||
if (StoredDeclsMap *Map = Primary->buildLookup())
|
||||
return all_lookups_iterator(Map->end(), Map->end());
|
||||
return all_lookups_iterator();
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
2276
thirdparty/clang/include/clang/AST/DeclObjC.h
vendored
Normal file
2276
thirdparty/clang/include/clang/AST/DeclObjC.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
83
thirdparty/clang/include/clang/AST/DeclOpenMP.h
vendored
Normal file
83
thirdparty/clang/include/clang/AST/DeclOpenMP.h
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
//===--- OpenMP.h - Classes for representing OpenMP directives ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file defines OpenMP nodes.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_OPENMP_H
|
||||
#define LLVM_CLANG_AST_OPENMP_H
|
||||
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class DeclRefExpr;
|
||||
|
||||
/// \brief This represents '#pragma omp threadprivate ...' directive.
|
||||
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
|
||||
///
|
||||
/// \code
|
||||
/// int a;
|
||||
/// #pragma omp threadprivate(a)
|
||||
/// struct A {
|
||||
/// static int b;
|
||||
/// #pragma omp threadprivate(b)
|
||||
/// };
|
||||
/// \endcode
|
||||
///
|
||||
class OMPThreadPrivateDecl : public Decl {
|
||||
friend class ASTDeclReader;
|
||||
unsigned NumVars;
|
||||
|
||||
virtual void anchor();
|
||||
|
||||
OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
|
||||
Decl(DK, DC, L), NumVars(0) { }
|
||||
|
||||
ArrayRef<const DeclRefExpr *> getVars() const {
|
||||
return ArrayRef<const DeclRefExpr *>(
|
||||
reinterpret_cast<const DeclRefExpr * const *>(this + 1),
|
||||
NumVars);
|
||||
}
|
||||
|
||||
llvm::MutableArrayRef<DeclRefExpr *> getVars() {
|
||||
return llvm::MutableArrayRef<DeclRefExpr *>(
|
||||
reinterpret_cast<DeclRefExpr **>(this + 1),
|
||||
NumVars);
|
||||
}
|
||||
|
||||
void setVars(ArrayRef<DeclRefExpr *> VL);
|
||||
|
||||
public:
|
||||
static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
ArrayRef<DeclRefExpr *> VL);
|
||||
static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID, unsigned N);
|
||||
|
||||
typedef llvm::MutableArrayRef<DeclRefExpr *>::iterator varlist_iterator;
|
||||
typedef ArrayRef<const DeclRefExpr *>::iterator varlist_const_iterator;
|
||||
|
||||
unsigned varlist_size() const { return NumVars; }
|
||||
bool varlist_empty() const { return NumVars == 0; }
|
||||
varlist_iterator varlist_begin() { return getVars().begin(); }
|
||||
varlist_iterator varlist_end() { return getVars().end(); }
|
||||
varlist_const_iterator varlist_begin() const { return getVars().begin(); }
|
||||
varlist_const_iterator varlist_end() const { return getVars().end(); }
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
2244
thirdparty/clang/include/clang/AST/DeclTemplate.h
vendored
Normal file
2244
thirdparty/clang/include/clang/AST/DeclTemplate.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
79
thirdparty/clang/include/clang/AST/DeclVisitor.h
vendored
Normal file
79
thirdparty/clang/include/clang/AST/DeclVisitor.h
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the DeclVisitor interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_DECLVISITOR_H
|
||||
#define LLVM_CLANG_AST_DECLVISITOR_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclFriend.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclOpenMP.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
|
||||
namespace clang {
|
||||
namespace declvisitor {
|
||||
|
||||
template <typename T> struct make_ptr { typedef T *type; };
|
||||
template <typename T> struct make_const_ptr { typedef const T *type; };
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
class Base {
|
||||
public:
|
||||
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(NAME, CLASS) \
|
||||
return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
|
||||
|
||||
RetTy Visit(PTR(Decl) D) {
|
||||
switch (D->getKind()) {
|
||||
#define DECL(DERIVED, BASE) \
|
||||
case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
|
||||
#define ABSTRACT_DECL(DECL)
|
||||
#include "clang/AST/DeclNodes.inc"
|
||||
}
|
||||
llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
|
||||
}
|
||||
|
||||
// If the implementation chooses not to implement a certain visit
|
||||
// method, fall back to the parent.
|
||||
#define DECL(DERIVED, BASE) \
|
||||
RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); }
|
||||
#include "clang/AST/DeclNodes.inc"
|
||||
|
||||
RetTy VisitDecl(PTR(Decl) D) { return RetTy(); }
|
||||
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
} // end namespace declvisitor
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
///
|
||||
/// This class does not preserve constness of Decl pointers (see also
|
||||
/// ConstDeclVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class DeclVisitor
|
||||
: public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
///
|
||||
/// This class preserves constness of Decl pointers (see also DeclVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class ConstDeclVisitor
|
||||
: public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_DECLVISITOR_H
|
||||
592
thirdparty/clang/include/clang/AST/DeclarationName.h
vendored
Normal file
592
thirdparty/clang/include/clang/AST/DeclarationName.h
vendored
Normal file
@@ -0,0 +1,592 @@
|
||||
//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the DeclarationName and DeclarationNameTable classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
|
||||
#define LLVM_CLANG_AST_DECLARATIONNAME_H
|
||||
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> struct DenseMapInfo;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CXXLiteralOperatorIdName;
|
||||
class CXXOperatorIdName;
|
||||
class CXXSpecialName;
|
||||
class DeclarationNameExtra;
|
||||
class IdentifierInfo;
|
||||
class MultiKeywordSelector;
|
||||
class QualType;
|
||||
class Type;
|
||||
class TypeSourceInfo;
|
||||
class UsingDirectiveDecl;
|
||||
|
||||
template <typename> class CanQual;
|
||||
typedef CanQual<Type> CanQualType;
|
||||
|
||||
/// DeclarationName - The name of a declaration. In the common case,
|
||||
/// this just stores an IdentifierInfo pointer to a normal
|
||||
/// name. However, it also provides encodings for Objective-C
|
||||
/// selectors (optimizing zero- and one-argument selectors, which make
|
||||
/// up 78% percent of all selectors in Cocoa.h) and special C++ names
|
||||
/// for constructors, destructors, and conversion functions.
|
||||
class DeclarationName {
|
||||
public:
|
||||
/// NameKind - The kind of name this object contains.
|
||||
enum NameKind {
|
||||
Identifier,
|
||||
ObjCZeroArgSelector,
|
||||
ObjCOneArgSelector,
|
||||
ObjCMultiArgSelector,
|
||||
CXXConstructorName,
|
||||
CXXDestructorName,
|
||||
CXXConversionFunctionName,
|
||||
CXXOperatorName,
|
||||
CXXLiteralOperatorName,
|
||||
CXXUsingDirective
|
||||
};
|
||||
|
||||
private:
|
||||
/// StoredNameKind - The kind of name that is actually stored in the
|
||||
/// upper bits of the Ptr field. This is only used internally.
|
||||
///
|
||||
/// Note: The entries here are synchronized with the entries in Selector,
|
||||
/// for efficient translation between the two.
|
||||
enum StoredNameKind {
|
||||
StoredIdentifier = 0,
|
||||
StoredObjCZeroArgSelector = 0x01,
|
||||
StoredObjCOneArgSelector = 0x02,
|
||||
StoredDeclarationNameExtra = 0x03,
|
||||
PtrMask = 0x03
|
||||
};
|
||||
|
||||
/// Ptr - The lowest two bits are used to express what kind of name
|
||||
/// we're actually storing, using the values of NameKind. Depending
|
||||
/// on the kind of name this is, the upper bits of Ptr may have one
|
||||
/// of several different meanings:
|
||||
///
|
||||
/// StoredIdentifier - The name is a normal identifier, and Ptr is
|
||||
/// a normal IdentifierInfo pointer.
|
||||
///
|
||||
/// StoredObjCZeroArgSelector - The name is an Objective-C
|
||||
/// selector with zero arguments, and Ptr is an IdentifierInfo
|
||||
/// pointer pointing to the selector name.
|
||||
///
|
||||
/// StoredObjCOneArgSelector - The name is an Objective-C selector
|
||||
/// with one argument, and Ptr is an IdentifierInfo pointer
|
||||
/// pointing to the selector name.
|
||||
///
|
||||
/// StoredDeclarationNameExtra - Ptr is actually a pointer to a
|
||||
/// DeclarationNameExtra structure, whose first value will tell us
|
||||
/// whether this is an Objective-C selector, C++ operator-id name,
|
||||
/// or special C++ name.
|
||||
uintptr_t Ptr;
|
||||
|
||||
/// getStoredNameKind - Return the kind of object that is stored in
|
||||
/// Ptr.
|
||||
StoredNameKind getStoredNameKind() const {
|
||||
return static_cast<StoredNameKind>(Ptr & PtrMask);
|
||||
}
|
||||
|
||||
/// getExtra - Get the "extra" information associated with this
|
||||
/// multi-argument selector or C++ special name.
|
||||
DeclarationNameExtra *getExtra() const {
|
||||
assert(getStoredNameKind() == StoredDeclarationNameExtra &&
|
||||
"Declaration name does not store an Extra structure");
|
||||
return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
|
||||
}
|
||||
|
||||
/// getAsCXXSpecialName - If the stored pointer is actually a
|
||||
/// CXXSpecialName, returns a pointer to it. Otherwise, returns
|
||||
/// a NULL pointer.
|
||||
CXXSpecialName *getAsCXXSpecialName() const {
|
||||
NameKind Kind = getNameKind();
|
||||
if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
|
||||
return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getAsCXXOperatorIdName
|
||||
CXXOperatorIdName *getAsCXXOperatorIdName() const {
|
||||
if (getNameKind() == CXXOperatorName)
|
||||
return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
|
||||
if (getNameKind() == CXXLiteralOperatorName)
|
||||
return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Construct a declaration name from the name of a C++ constructor,
|
||||
// destructor, or conversion function.
|
||||
DeclarationName(CXXSpecialName *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
// Construct a declaration name from the name of a C++ overloaded
|
||||
// operator.
|
||||
DeclarationName(CXXOperatorIdName *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
DeclarationName(CXXLiteralOperatorIdName *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
/// Construct a declaration name from a raw pointer.
|
||||
DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
|
||||
|
||||
friend class DeclarationNameTable;
|
||||
friend class NamedDecl;
|
||||
|
||||
/// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
|
||||
/// for this name as a void pointer if it's not an identifier.
|
||||
void *getFETokenInfoAsVoidSlow() const;
|
||||
|
||||
public:
|
||||
/// DeclarationName - Used to create an empty selector.
|
||||
DeclarationName() : Ptr(0) { }
|
||||
|
||||
// Construct a declaration name from an IdentifierInfo *.
|
||||
DeclarationName(const IdentifierInfo *II)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(II)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
|
||||
}
|
||||
|
||||
// Construct a declaration name from an Objective-C selector.
|
||||
DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
|
||||
|
||||
/// getUsingDirectiveName - Return name for all using-directives.
|
||||
static DeclarationName getUsingDirectiveName();
|
||||
|
||||
// operator bool() - Evaluates true when this declaration name is
|
||||
// non-empty.
|
||||
operator bool() const {
|
||||
return ((Ptr & PtrMask) != 0) ||
|
||||
(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
|
||||
}
|
||||
|
||||
/// Predicate functions for querying what type of name this is.
|
||||
bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
|
||||
bool isObjCZeroArgSelector() const {
|
||||
return getStoredNameKind() == StoredObjCZeroArgSelector;
|
||||
}
|
||||
bool isObjCOneArgSelector() const {
|
||||
return getStoredNameKind() == StoredObjCOneArgSelector;
|
||||
}
|
||||
|
||||
/// getNameKind - Determine what kind of name this is.
|
||||
NameKind getNameKind() const;
|
||||
|
||||
/// \brief Determines whether the name itself is dependent, e.g., because it
|
||||
/// involves a C++ type that is itself dependent.
|
||||
///
|
||||
/// Note that this does not capture all of the notions of "dependent name",
|
||||
/// because an identifier can be a dependent name if it is used as the
|
||||
/// callee in a call expression with dependent arguments.
|
||||
bool isDependentName() const;
|
||||
|
||||
/// getNameAsString - Retrieve the human-readable string for this name.
|
||||
std::string getAsString() const;
|
||||
|
||||
/// printName - Print the human-readable name to a stream.
|
||||
void printName(raw_ostream &OS) const;
|
||||
|
||||
/// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
|
||||
/// this declaration name, or NULL if this declaration name isn't a
|
||||
/// simple identifier.
|
||||
IdentifierInfo *getAsIdentifierInfo() const {
|
||||
if (isIdentifier())
|
||||
return reinterpret_cast<IdentifierInfo *>(Ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getAsOpaqueInteger - Get the representation of this declaration
|
||||
/// name as an opaque integer.
|
||||
uintptr_t getAsOpaqueInteger() const { return Ptr; }
|
||||
|
||||
/// getAsOpaquePtr - Get the representation of this declaration name as
|
||||
/// an opaque pointer.
|
||||
void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
|
||||
|
||||
static DeclarationName getFromOpaquePtr(void *P) {
|
||||
DeclarationName N;
|
||||
N.Ptr = reinterpret_cast<uintptr_t> (P);
|
||||
return N;
|
||||
}
|
||||
|
||||
static DeclarationName getFromOpaqueInteger(uintptr_t P) {
|
||||
DeclarationName N;
|
||||
N.Ptr = P;
|
||||
return N;
|
||||
}
|
||||
|
||||
/// getCXXNameType - If this name is one of the C++ names (of a
|
||||
/// constructor, destructor, or conversion function), return the
|
||||
/// type associated with that name.
|
||||
QualType getCXXNameType() const;
|
||||
|
||||
/// getCXXOverloadedOperator - If this name is the name of an
|
||||
/// overloadable operator in C++ (e.g., @c operator+), retrieve the
|
||||
/// kind of overloaded operator.
|
||||
OverloadedOperatorKind getCXXOverloadedOperator() const;
|
||||
|
||||
/// getCXXLiteralIdentifier - If this name is the name of a literal
|
||||
/// operator, retrieve the identifier associated with it.
|
||||
IdentifierInfo *getCXXLiteralIdentifier() const;
|
||||
|
||||
/// getObjCSelector - Get the Objective-C selector stored in this
|
||||
/// declaration name.
|
||||
Selector getObjCSelector() const {
|
||||
assert((getNameKind() == ObjCZeroArgSelector ||
|
||||
getNameKind() == ObjCOneArgSelector ||
|
||||
getNameKind() == ObjCMultiArgSelector ||
|
||||
Ptr == 0) && "Not a selector!");
|
||||
return Selector(Ptr);
|
||||
}
|
||||
|
||||
/// getFETokenInfo/setFETokenInfo - The language front-end is
|
||||
/// allowed to associate arbitrary metadata with some kinds of
|
||||
/// declaration names, including normal identifiers and C++
|
||||
/// constructors, destructors, and conversion functions.
|
||||
template<typename T>
|
||||
T *getFETokenInfo() const {
|
||||
if (const IdentifierInfo *Info = getAsIdentifierInfo())
|
||||
return Info->getFETokenInfo<T>();
|
||||
return static_cast<T*>(getFETokenInfoAsVoidSlow());
|
||||
}
|
||||
|
||||
void setFETokenInfo(void *T);
|
||||
|
||||
/// operator== - Determine whether the specified names are identical..
|
||||
friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
|
||||
return LHS.Ptr == RHS.Ptr;
|
||||
}
|
||||
|
||||
/// operator!= - Determine whether the specified names are different.
|
||||
friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
|
||||
return LHS.Ptr != RHS.Ptr;
|
||||
}
|
||||
|
||||
static DeclarationName getEmptyMarker() {
|
||||
return DeclarationName(uintptr_t(-1));
|
||||
}
|
||||
|
||||
static DeclarationName getTombstoneMarker() {
|
||||
return DeclarationName(uintptr_t(-2));
|
||||
}
|
||||
|
||||
static int compare(DeclarationName LHS, DeclarationName RHS);
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
/// Ordering on two declaration names. If both names are identifiers,
|
||||
/// this provides a lexicographical ordering.
|
||||
inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
|
||||
return DeclarationName::compare(LHS, RHS) < 0;
|
||||
}
|
||||
|
||||
/// Ordering on two declaration names. If both names are identifiers,
|
||||
/// this provides a lexicographical ordering.
|
||||
inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
|
||||
return DeclarationName::compare(LHS, RHS) > 0;
|
||||
}
|
||||
|
||||
/// Ordering on two declaration names. If both names are identifiers,
|
||||
/// this provides a lexicographical ordering.
|
||||
inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
|
||||
return DeclarationName::compare(LHS, RHS) <= 0;
|
||||
}
|
||||
|
||||
/// Ordering on two declaration names. If both names are identifiers,
|
||||
/// this provides a lexicographical ordering.
|
||||
inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
|
||||
return DeclarationName::compare(LHS, RHS) >= 0;
|
||||
}
|
||||
|
||||
/// DeclarationNameTable - Used to store and retrieve DeclarationName
|
||||
/// instances for the various kinds of declaration names, e.g., normal
|
||||
/// identifiers, C++ constructor names, etc. This class contains
|
||||
/// uniqued versions of each of the C++ special names, which can be
|
||||
/// retrieved using its member functions (e.g.,
|
||||
/// getCXXConstructorName).
|
||||
class DeclarationNameTable {
|
||||
const ASTContext &Ctx;
|
||||
void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
|
||||
CXXOperatorIdName *CXXOperatorNames; // Operator names
|
||||
void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
|
||||
|
||||
DeclarationNameTable(const DeclarationNameTable&) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const DeclarationNameTable&) LLVM_DELETED_FUNCTION;
|
||||
|
||||
public:
|
||||
DeclarationNameTable(const ASTContext &C);
|
||||
~DeclarationNameTable();
|
||||
|
||||
/// getIdentifier - Create a declaration name that is a simple
|
||||
/// identifier.
|
||||
DeclarationName getIdentifier(const IdentifierInfo *ID) {
|
||||
return DeclarationName(ID);
|
||||
}
|
||||
|
||||
/// getCXXConstructorName - Returns the name of a C++ constructor
|
||||
/// for the given Type.
|
||||
DeclarationName getCXXConstructorName(CanQualType Ty);
|
||||
|
||||
/// getCXXDestructorName - Returns the name of a C++ destructor
|
||||
/// for the given Type.
|
||||
DeclarationName getCXXDestructorName(CanQualType Ty);
|
||||
|
||||
/// getCXXConversionFunctionName - Returns the name of a C++
|
||||
/// conversion function for the given Type.
|
||||
DeclarationName getCXXConversionFunctionName(CanQualType Ty);
|
||||
|
||||
/// getCXXSpecialName - Returns a declaration name for special kind
|
||||
/// of C++ name, e.g., for a constructor, destructor, or conversion
|
||||
/// function.
|
||||
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
|
||||
CanQualType Ty);
|
||||
|
||||
/// getCXXOperatorName - Get the name of the overloadable C++
|
||||
/// operator corresponding to Op.
|
||||
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
|
||||
|
||||
/// getCXXLiteralOperatorName - Get the name of the literal operator function
|
||||
/// with II as the identifier.
|
||||
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
|
||||
};
|
||||
|
||||
/// DeclarationNameLoc - Additional source/type location info
|
||||
/// for a declaration name. Needs a DeclarationName in order
|
||||
/// to be interpreted correctly.
|
||||
struct DeclarationNameLoc {
|
||||
// The source location for identifier stored elsewhere.
|
||||
// struct {} Identifier;
|
||||
|
||||
// Type info for constructors, destructors and conversion functions.
|
||||
// Locations (if any) for the tilde (destructor) or operator keyword
|
||||
// (conversion) are stored elsewhere.
|
||||
struct NT {
|
||||
TypeSourceInfo* TInfo;
|
||||
};
|
||||
|
||||
// The location (if any) of the operator keyword is stored elsewhere.
|
||||
struct CXXOpName {
|
||||
unsigned BeginOpNameLoc;
|
||||
unsigned EndOpNameLoc;
|
||||
};
|
||||
|
||||
// The location (if any) of the operator keyword is stored elsewhere.
|
||||
struct CXXLitOpName {
|
||||
unsigned OpNameLoc;
|
||||
};
|
||||
|
||||
// struct {} CXXUsingDirective;
|
||||
// struct {} ObjCZeroArgSelector;
|
||||
// struct {} ObjCOneArgSelector;
|
||||
// struct {} ObjCMultiArgSelector;
|
||||
union {
|
||||
struct NT NamedType;
|
||||
struct CXXOpName CXXOperatorName;
|
||||
struct CXXLitOpName CXXLiteralOperatorName;
|
||||
};
|
||||
|
||||
DeclarationNameLoc(DeclarationName Name);
|
||||
// FIXME: this should go away once all DNLocs are properly initialized.
|
||||
DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
|
||||
}; // struct DeclarationNameLoc
|
||||
|
||||
|
||||
/// DeclarationNameInfo - A collector data type for bundling together
|
||||
/// a DeclarationName and the correspnding source/type location info.
|
||||
struct DeclarationNameInfo {
|
||||
private:
|
||||
/// Name - The declaration name, also encoding name kind.
|
||||
DeclarationName Name;
|
||||
/// Loc - The main source location for the declaration name.
|
||||
SourceLocation NameLoc;
|
||||
/// Info - Further source/type location info for special kinds of names.
|
||||
DeclarationNameLoc LocInfo;
|
||||
|
||||
public:
|
||||
// FIXME: remove it.
|
||||
DeclarationNameInfo() {}
|
||||
|
||||
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
|
||||
: Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
|
||||
|
||||
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
|
||||
DeclarationNameLoc LocInfo)
|
||||
: Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
|
||||
|
||||
/// getName - Returns the embedded declaration name.
|
||||
DeclarationName getName() const { return Name; }
|
||||
/// setName - Sets the embedded declaration name.
|
||||
void setName(DeclarationName N) { Name = N; }
|
||||
|
||||
/// getLoc - Returns the main location of the declaration name.
|
||||
SourceLocation getLoc() const { return NameLoc; }
|
||||
/// setLoc - Sets the main location of the declaration name.
|
||||
void setLoc(SourceLocation L) { NameLoc = L; }
|
||||
|
||||
const DeclarationNameLoc &getInfo() const { return LocInfo; }
|
||||
DeclarationNameLoc &getInfo() { return LocInfo; }
|
||||
void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
|
||||
|
||||
/// getNamedTypeInfo - Returns the source type info associated to
|
||||
/// the name. Assumes it is a constructor, destructor or conversion.
|
||||
TypeSourceInfo *getNamedTypeInfo() const {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
|
||||
Name.getNameKind() == DeclarationName::CXXDestructorName ||
|
||||
Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
|
||||
return LocInfo.NamedType.TInfo;
|
||||
}
|
||||
/// setNamedTypeInfo - Sets the source type info associated to
|
||||
/// the name. Assumes it is a constructor, destructor or conversion.
|
||||
void setNamedTypeInfo(TypeSourceInfo *TInfo) {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
|
||||
Name.getNameKind() == DeclarationName::CXXDestructorName ||
|
||||
Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
|
||||
LocInfo.NamedType.TInfo = TInfo;
|
||||
}
|
||||
|
||||
/// getCXXOperatorNameRange - Gets the range of the operator name
|
||||
/// (without the operator keyword). Assumes it is a (non-literal) operator.
|
||||
SourceRange getCXXOperatorNameRange() const {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
|
||||
return SourceRange(
|
||||
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
|
||||
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
|
||||
);
|
||||
}
|
||||
/// setCXXOperatorNameRange - Sets the range of the operator name
|
||||
/// (without the operator keyword). Assumes it is a C++ operator.
|
||||
void setCXXOperatorNameRange(SourceRange R) {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
|
||||
LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
|
||||
LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
|
||||
}
|
||||
|
||||
/// getCXXLiteralOperatorNameLoc - Returns the location of the literal
|
||||
/// operator name (not the operator keyword).
|
||||
/// Assumes it is a literal operator.
|
||||
SourceLocation getCXXLiteralOperatorNameLoc() const {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
|
||||
return SourceLocation::
|
||||
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
|
||||
}
|
||||
/// setCXXLiteralOperatorNameLoc - Sets the location of the literal
|
||||
/// operator name (not the operator keyword).
|
||||
/// Assumes it is a literal operator.
|
||||
void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
|
||||
LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this name involves a template parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Determine whether this name contains an unexpanded
|
||||
/// parameter pack.
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
||||
/// getAsString - Retrieve the human-readable string for this name.
|
||||
std::string getAsString() const;
|
||||
|
||||
/// printName - Print the human-readable name to a stream.
|
||||
void printName(raw_ostream &OS) const;
|
||||
|
||||
/// getBeginLoc - Retrieve the location of the first token.
|
||||
SourceLocation getBeginLoc() const { return NameLoc; }
|
||||
/// getEndLoc - Retrieve the location of the last token.
|
||||
SourceLocation getEndLoc() const;
|
||||
/// getSourceRange - The range of the declaration name.
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return SourceRange(getLocStart(), getLocEnd());
|
||||
}
|
||||
SourceLocation getLocStart() const LLVM_READONLY {
|
||||
return getBeginLoc();
|
||||
}
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
SourceLocation EndLoc = getEndLoc();
|
||||
return EndLoc.isValid() ? EndLoc : getLocStart();
|
||||
}
|
||||
};
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending DeclarationName's
|
||||
/// into a diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
DeclarationName N) {
|
||||
DB.AddTaggedVal(N.getAsOpaqueInteger(),
|
||||
DiagnosticsEngine::ak_declarationname);
|
||||
return DB;
|
||||
}
|
||||
|
||||
/// Insertion operator for partial diagnostics. This allows binding
|
||||
/// DeclarationName's into a partial diagnostic with <<.
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
DeclarationName N) {
|
||||
PD.AddTaggedVal(N.getAsOpaqueInteger(),
|
||||
DiagnosticsEngine::ak_declarationname);
|
||||
return PD;
|
||||
}
|
||||
|
||||
inline raw_ostream &operator<<(raw_ostream &OS,
|
||||
DeclarationNameInfo DNInfo) {
|
||||
DNInfo.printName(OS);
|
||||
return OS;
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
namespace llvm {
|
||||
/// Define DenseMapInfo so that DeclarationNames can be used as keys
|
||||
/// in DenseMap and DenseSets.
|
||||
template<>
|
||||
struct DenseMapInfo<clang::DeclarationName> {
|
||||
static inline clang::DeclarationName getEmptyKey() {
|
||||
return clang::DeclarationName::getEmptyMarker();
|
||||
}
|
||||
|
||||
static inline clang::DeclarationName getTombstoneKey() {
|
||||
return clang::DeclarationName::getTombstoneMarker();
|
||||
}
|
||||
|
||||
static unsigned getHashValue(clang::DeclarationName Name) {
|
||||
return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
|
||||
}
|
||||
|
||||
static inline bool
|
||||
isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct isPodLike<clang::DeclarationName> { static const bool value = true; };
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
190
thirdparty/clang/include/clang/AST/DependentDiagnostic.h
vendored
Normal file
190
thirdparty/clang/include/clang/AST/DependentDiagnostic.h
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines interfaces for diagnostics which may or may
|
||||
// fire based on how a template is instantiated.
|
||||
//
|
||||
// At the moment, the only consumer of this interface is access
|
||||
// control.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
|
||||
#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
|
||||
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclContextInternals.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class CXXRecordDecl;
|
||||
class NamedDecl;
|
||||
|
||||
/// A dependently-generated diagnostic.
|
||||
class DependentDiagnostic {
|
||||
public:
|
||||
enum AccessNonce { Access = 0 };
|
||||
|
||||
static DependentDiagnostic *Create(ASTContext &Context,
|
||||
DeclContext *Parent,
|
||||
AccessNonce _,
|
||||
SourceLocation Loc,
|
||||
bool IsMemberAccess,
|
||||
AccessSpecifier AS,
|
||||
NamedDecl *TargetDecl,
|
||||
CXXRecordDecl *NamingClass,
|
||||
QualType BaseObjectType,
|
||||
const PartialDiagnostic &PDiag) {
|
||||
DependentDiagnostic *DD = Create(Context, Parent, PDiag);
|
||||
DD->AccessData.Loc = Loc.getRawEncoding();
|
||||
DD->AccessData.IsMember = IsMemberAccess;
|
||||
DD->AccessData.Access = AS;
|
||||
DD->AccessData.TargetDecl = TargetDecl;
|
||||
DD->AccessData.NamingClass = NamingClass;
|
||||
DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
|
||||
return DD;
|
||||
}
|
||||
|
||||
unsigned getKind() const {
|
||||
return Access;
|
||||
}
|
||||
|
||||
bool isAccessToMember() const {
|
||||
assert(getKind() == Access);
|
||||
return AccessData.IsMember;
|
||||
}
|
||||
|
||||
AccessSpecifier getAccess() const {
|
||||
assert(getKind() == Access);
|
||||
return AccessSpecifier(AccessData.Access);
|
||||
}
|
||||
|
||||
SourceLocation getAccessLoc() const {
|
||||
assert(getKind() == Access);
|
||||
return SourceLocation::getFromRawEncoding(AccessData.Loc);
|
||||
}
|
||||
|
||||
NamedDecl *getAccessTarget() const {
|
||||
assert(getKind() == Access);
|
||||
return AccessData.TargetDecl;
|
||||
}
|
||||
|
||||
NamedDecl *getAccessNamingClass() const {
|
||||
assert(getKind() == Access);
|
||||
return AccessData.NamingClass;
|
||||
}
|
||||
|
||||
QualType getAccessBaseObjectType() const {
|
||||
assert(getKind() == Access);
|
||||
return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
|
||||
}
|
||||
|
||||
const PartialDiagnostic &getDiagnostic() const {
|
||||
return Diag;
|
||||
}
|
||||
|
||||
private:
|
||||
DependentDiagnostic(const PartialDiagnostic &PDiag,
|
||||
PartialDiagnostic::Storage *Storage)
|
||||
: Diag(PDiag, Storage) {}
|
||||
|
||||
static DependentDiagnostic *Create(ASTContext &Context,
|
||||
DeclContext *Parent,
|
||||
const PartialDiagnostic &PDiag);
|
||||
|
||||
friend class DependentStoredDeclsMap;
|
||||
friend class DeclContext::ddiag_iterator;
|
||||
DependentDiagnostic *NextDiagnostic;
|
||||
|
||||
PartialDiagnostic Diag;
|
||||
|
||||
struct {
|
||||
unsigned Loc;
|
||||
unsigned Access : 2;
|
||||
unsigned IsMember : 1;
|
||||
NamedDecl *TargetDecl;
|
||||
CXXRecordDecl *NamingClass;
|
||||
void *BaseObjectType;
|
||||
} AccessData;
|
||||
};
|
||||
|
||||
///
|
||||
|
||||
/// An iterator over the dependent diagnostics in a dependent context.
|
||||
class DeclContext::ddiag_iterator {
|
||||
public:
|
||||
ddiag_iterator() : Ptr(0) {}
|
||||
explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
|
||||
|
||||
typedef DependentDiagnostic *value_type;
|
||||
typedef DependentDiagnostic *reference;
|
||||
typedef DependentDiagnostic *pointer;
|
||||
typedef int difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
reference operator*() const { return Ptr; }
|
||||
|
||||
ddiag_iterator &operator++() {
|
||||
assert(Ptr && "attempt to increment past end of diag list");
|
||||
Ptr = Ptr->NextDiagnostic;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ddiag_iterator operator++(int) {
|
||||
ddiag_iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(ddiag_iterator Other) const {
|
||||
return Ptr == Other.Ptr;
|
||||
}
|
||||
|
||||
bool operator!=(ddiag_iterator Other) const {
|
||||
return Ptr != Other.Ptr;
|
||||
}
|
||||
|
||||
ddiag_iterator &operator+=(difference_type N) {
|
||||
assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
|
||||
while (N--)
|
||||
++*this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ddiag_iterator operator+(difference_type N) const {
|
||||
ddiag_iterator tmp = *this;
|
||||
tmp += N;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
DependentDiagnostic *Ptr;
|
||||
};
|
||||
|
||||
inline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const {
|
||||
assert(isDependentContext()
|
||||
&& "cannot iterate dependent diagnostics of non-dependent context");
|
||||
const DependentStoredDeclsMap *Map
|
||||
= static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
|
||||
|
||||
if (!Map) return ddiag_iterator();
|
||||
return ddiag_iterator(Map->FirstDiagnostic);
|
||||
}
|
||||
|
||||
inline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
|
||||
return ddiag_iterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
86
thirdparty/clang/include/clang/AST/EvaluatedExprVisitor.h
vendored
Normal file
86
thirdparty/clang/include/clang/AST/EvaluatedExprVisitor.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
//===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the EvaluatedExprVisitor class template, which visits
|
||||
// the potentially-evaluated subexpressions of a potentially-evaluated
|
||||
// expression.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
|
||||
#define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
|
||||
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
|
||||
/// \brief Given a potentially-evaluated expression, this visitor visits all
|
||||
/// of its potentially-evaluated subexpressions, recursively.
|
||||
template<typename ImplClass>
|
||||
class EvaluatedExprVisitor : public StmtVisitor<ImplClass> {
|
||||
ASTContext &Context;
|
||||
|
||||
public:
|
||||
explicit EvaluatedExprVisitor(ASTContext &Context) : Context(Context) { }
|
||||
|
||||
// Expressions that have no potentially-evaluated subexpressions (but may have
|
||||
// other sub-expressions).
|
||||
void VisitDeclRefExpr(DeclRefExpr *E) { }
|
||||
void VisitOffsetOfExpr(OffsetOfExpr *E) { }
|
||||
void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
|
||||
void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { }
|
||||
void VisitBlockExpr(BlockExpr *E) { }
|
||||
void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
|
||||
void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
|
||||
|
||||
void VisitMemberExpr(MemberExpr *E) {
|
||||
// Only the base matters.
|
||||
return this->Visit(E->getBase());
|
||||
}
|
||||
|
||||
void VisitChooseExpr(ChooseExpr *E) {
|
||||
// Don't visit either child expression if the condition is dependent.
|
||||
if (E->getCond()->isValueDependent())
|
||||
return;
|
||||
// Only the selected subexpression matters; the other one is not evaluated.
|
||||
return this->Visit(E->getChosenSubExpr(Context));
|
||||
}
|
||||
|
||||
void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
|
||||
// Only the actual initializer matters; the designators are all constant
|
||||
// expressions.
|
||||
return this->Visit(E->getInit());
|
||||
}
|
||||
|
||||
void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
||||
if (E->isPotentiallyEvaluated())
|
||||
return this->Visit(E->getExprOperand());
|
||||
}
|
||||
|
||||
void VisitCallExpr(CallExpr *CE) {
|
||||
if (!CE->isUnevaluatedBuiltinCall(Context))
|
||||
return static_cast<ImplClass*>(this)->VisitExpr(CE);
|
||||
}
|
||||
|
||||
/// \brief The basis case walks all of the children of the statement or
|
||||
/// expression, assuming they are all potentially evaluated.
|
||||
void VisitStmt(Stmt *S) {
|
||||
for (Stmt::child_range C = S->children(); C; ++C)
|
||||
if (*C)
|
||||
this->Visit(*C);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
|
||||
4715
thirdparty/clang/include/clang/AST/Expr.h
vendored
Normal file
4715
thirdparty/clang/include/clang/AST/Expr.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3846
thirdparty/clang/include/clang/AST/ExprCXX.h
vendored
Normal file
3846
thirdparty/clang/include/clang/AST/ExprCXX.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1570
thirdparty/clang/include/clang/AST/ExprObjC.h
vendored
Normal file
1570
thirdparty/clang/include/clang/AST/ExprObjC.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
539
thirdparty/clang/include/clang/AST/ExternalASTSource.h
vendored
Normal file
539
thirdparty/clang/include/clang/AST/ExternalASTSource.h
vendored
Normal file
@@ -0,0 +1,539 @@
|
||||
//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ExternalASTSource interface, which enables
|
||||
// construction of AST nodes from some external source.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
|
||||
#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTConsumer;
|
||||
class CXXBaseSpecifier;
|
||||
class DeclarationName;
|
||||
class ExternalSemaSource; // layering violation required for downcasting
|
||||
class FieldDecl;
|
||||
class Module;
|
||||
class NamedDecl;
|
||||
class RecordDecl;
|
||||
class Selector;
|
||||
class Stmt;
|
||||
class TagDecl;
|
||||
|
||||
/// \brief Enumeration describing the result of loading information from
|
||||
/// an external source.
|
||||
enum ExternalLoadResult {
|
||||
/// \brief Loading the external information has succeeded.
|
||||
ELR_Success,
|
||||
|
||||
/// \brief Loading the external information has failed.
|
||||
ELR_Failure,
|
||||
|
||||
/// \brief The external information has already been loaded, and therefore
|
||||
/// no additional processing is required.
|
||||
ELR_AlreadyLoaded
|
||||
};
|
||||
|
||||
/// \brief Abstract interface for external sources of AST nodes.
|
||||
///
|
||||
/// External AST sources provide AST nodes constructed from some
|
||||
/// external source, such as a precompiled header. External AST
|
||||
/// sources can resolve types and declarations from abstract IDs into
|
||||
/// actual type and declaration nodes, and read parts of declaration
|
||||
/// contexts.
|
||||
class ExternalASTSource {
|
||||
/// \brief Whether this AST source also provides information for
|
||||
/// semantic analysis.
|
||||
bool SemaSource;
|
||||
|
||||
friend class ExternalSemaSource;
|
||||
|
||||
public:
|
||||
ExternalASTSource() : SemaSource(false) { }
|
||||
|
||||
virtual ~ExternalASTSource();
|
||||
|
||||
/// \brief RAII class for safely pairing a StartedDeserializing call
|
||||
/// with FinishedDeserializing.
|
||||
class Deserializing {
|
||||
ExternalASTSource *Source;
|
||||
public:
|
||||
explicit Deserializing(ExternalASTSource *source) : Source(source) {
|
||||
assert(Source);
|
||||
Source->StartedDeserializing();
|
||||
}
|
||||
~Deserializing() {
|
||||
Source->FinishedDeserializing();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Resolve a declaration ID into a declaration, potentially
|
||||
/// building a new declaration.
|
||||
///
|
||||
/// This method only needs to be implemented if the AST source ever
|
||||
/// passes back decl sets as VisibleDeclaration objects.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual Decl *GetExternalDecl(uint32_t ID);
|
||||
|
||||
/// \brief Resolve a selector ID into a selector.
|
||||
///
|
||||
/// This operation only needs to be implemented if the AST source
|
||||
/// returns non-zero for GetNumKnownSelectors().
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual Selector GetExternalSelector(uint32_t ID);
|
||||
|
||||
/// \brief Returns the number of selectors known to the external AST
|
||||
/// source.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual uint32_t GetNumExternalSelectors();
|
||||
|
||||
/// \brief Resolve the offset of a statement in the decl stream into
|
||||
/// a statement.
|
||||
///
|
||||
/// This operation is meant to be used via a LazyOffsetPtr. It only
|
||||
/// needs to be implemented if the AST source uses methods like
|
||||
/// FunctionDecl::setLazyBody when building decls.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
|
||||
|
||||
/// \brief Resolve the offset of a set of C++ base specifiers in the decl
|
||||
/// stream into an array of specifiers.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
|
||||
|
||||
/// \brief Update an out-of-date identifier.
|
||||
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
|
||||
|
||||
/// \brief Find all declarations with the given name in the given context,
|
||||
/// and add them to the context by calling SetExternalVisibleDeclsForName
|
||||
/// or SetNoExternalVisibleDeclsForName.
|
||||
/// \return \c true if any declarations might have been found, \c false if
|
||||
/// we definitely have no declarations with tbis name.
|
||||
///
|
||||
/// The default implementation of this method is a no-op returning \c false.
|
||||
virtual bool
|
||||
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
|
||||
|
||||
/// \brief Ensures that the table of all visible declarations inside this
|
||||
/// context is up to date.
|
||||
///
|
||||
/// The default implementation of this function is a no-op.
|
||||
virtual void completeVisibleDeclsMap(const DeclContext *DC);
|
||||
|
||||
/// \brief Retrieve the module that corresponds to the given module ID.
|
||||
virtual Module *getModule(unsigned ID) { return 0; }
|
||||
|
||||
/// \brief Finds all declarations lexically contained within the given
|
||||
/// DeclContext, after applying an optional filter predicate.
|
||||
///
|
||||
/// \param isKindWeWant a predicate function that returns true if the passed
|
||||
/// declaration kind is one we are looking for. If NULL, all declarations
|
||||
/// are returned.
|
||||
///
|
||||
/// \return an indication of whether the load succeeded or failed.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
bool (*isKindWeWant)(Decl::Kind),
|
||||
SmallVectorImpl<Decl*> &Result);
|
||||
|
||||
/// \brief Finds all declarations lexically contained within the given
|
||||
/// DeclContext.
|
||||
///
|
||||
/// \return true if an error occurred
|
||||
ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
SmallVectorImpl<Decl*> &Result) {
|
||||
return FindExternalLexicalDecls(DC, 0, Result);
|
||||
}
|
||||
|
||||
template <typename DeclTy>
|
||||
ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
|
||||
SmallVectorImpl<Decl*> &Result) {
|
||||
return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
|
||||
}
|
||||
|
||||
/// \brief Get the decls that are contained in a file in the Offset/Length
|
||||
/// range. \p Length can be 0 to indicate a point at \p Offset instead of
|
||||
/// a range.
|
||||
virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
|
||||
SmallVectorImpl<Decl *> &Decls) {}
|
||||
|
||||
/// \brief Gives the external AST source an opportunity to complete
|
||||
/// an incomplete type.
|
||||
virtual void CompleteType(TagDecl *Tag) {}
|
||||
|
||||
/// \brief Gives the external AST source an opportunity to complete an
|
||||
/// incomplete Objective-C class.
|
||||
///
|
||||
/// This routine will only be invoked if the "externally completed" bit is
|
||||
/// set on the ObjCInterfaceDecl via the function
|
||||
/// \c ObjCInterfaceDecl::setExternallyCompleted().
|
||||
virtual void CompleteType(ObjCInterfaceDecl *Class) { }
|
||||
|
||||
/// \brief Loads comment ranges.
|
||||
virtual void ReadComments() { }
|
||||
|
||||
/// \brief Notify ExternalASTSource that we started deserialization of
|
||||
/// a decl or type so until FinishedDeserializing is called there may be
|
||||
/// decls that are initializing. Must be paired with FinishedDeserializing.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void StartedDeserializing() { }
|
||||
|
||||
/// \brief Notify ExternalASTSource that we finished the deserialization of
|
||||
/// a decl or type. Must be paired with StartedDeserializing.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void FinishedDeserializing() { }
|
||||
|
||||
/// \brief Function that will be invoked when we begin parsing a new
|
||||
/// translation unit involving this external AST source.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
|
||||
|
||||
/// \brief Print any statistics that have been gathered regarding
|
||||
/// the external AST source.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void PrintStats();
|
||||
|
||||
|
||||
/// \brief Perform layout on the given record.
|
||||
///
|
||||
/// This routine allows the external AST source to provide an specific
|
||||
/// layout for a record, overriding the layout that would normally be
|
||||
/// constructed. It is intended for clients who receive specific layout
|
||||
/// details rather than source code (such as LLDB). The client is expected
|
||||
/// to fill in the field offsets, base offsets, virtual base offsets, and
|
||||
/// complete object size.
|
||||
///
|
||||
/// \param Record The record whose layout is being requested.
|
||||
///
|
||||
/// \param Size The final size of the record, in bits.
|
||||
///
|
||||
/// \param Alignment The final alignment of the record, in bits.
|
||||
///
|
||||
/// \param FieldOffsets The offset of each of the fields within the record,
|
||||
/// expressed in bits. All of the fields must be provided with offsets.
|
||||
///
|
||||
/// \param BaseOffsets The offset of each of the direct, non-virtual base
|
||||
/// classes. If any bases are not given offsets, the bases will be laid
|
||||
/// out according to the ABI.
|
||||
///
|
||||
/// \param VirtualBaseOffsets The offset of each of the virtual base classes
|
||||
/// (either direct or not). If any bases are not given offsets, the bases will be laid
|
||||
/// out according to the ABI.
|
||||
///
|
||||
/// \returns true if the record layout was provided, false otherwise.
|
||||
virtual bool
|
||||
layoutRecordType(const RecordDecl *Record,
|
||||
uint64_t &Size, uint64_t &Alignment,
|
||||
llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
|
||||
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
|
||||
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Queries for performance analysis.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
struct MemoryBufferSizes {
|
||||
size_t malloc_bytes;
|
||||
size_t mmap_bytes;
|
||||
|
||||
MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
|
||||
: malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
|
||||
};
|
||||
|
||||
/// Return the amount of memory used by memory buffers, breaking down
|
||||
/// by heap-backed versus mmap'ed memory.
|
||||
MemoryBufferSizes getMemoryBufferSizes() const {
|
||||
MemoryBufferSizes sizes(0, 0);
|
||||
getMemoryBufferSizes(sizes);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
|
||||
|
||||
protected:
|
||||
static DeclContextLookupResult
|
||||
SetExternalVisibleDeclsForName(const DeclContext *DC,
|
||||
DeclarationName Name,
|
||||
ArrayRef<NamedDecl*> Decls);
|
||||
|
||||
static DeclContextLookupResult
|
||||
SetNoExternalVisibleDeclsForName(const DeclContext *DC,
|
||||
DeclarationName Name);
|
||||
};
|
||||
|
||||
/// \brief A lazy pointer to an AST node (of base type T) that resides
|
||||
/// within an external AST source.
|
||||
///
|
||||
/// The AST node is identified within the external AST source by a
|
||||
/// 63-bit offset, and can be retrieved via an operation on the
|
||||
/// external AST source itself.
|
||||
template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
|
||||
struct LazyOffsetPtr {
|
||||
/// \brief Either a pointer to an AST node or the offset within the
|
||||
/// external AST source where the AST node can be found.
|
||||
///
|
||||
/// If the low bit is clear, a pointer to the AST node. If the low
|
||||
/// bit is set, the upper 63 bits are the offset.
|
||||
mutable uint64_t Ptr;
|
||||
|
||||
public:
|
||||
LazyOffsetPtr() : Ptr(0) { }
|
||||
|
||||
explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
|
||||
explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
|
||||
assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
|
||||
if (Offset == 0)
|
||||
Ptr = 0;
|
||||
}
|
||||
|
||||
LazyOffsetPtr &operator=(T *Ptr) {
|
||||
this->Ptr = reinterpret_cast<uint64_t>(Ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LazyOffsetPtr &operator=(uint64_t Offset) {
|
||||
assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
|
||||
if (Offset == 0)
|
||||
Ptr = 0;
|
||||
else
|
||||
Ptr = (Offset << 1) | 0x01;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Whether this pointer is non-NULL.
|
||||
///
|
||||
/// This operation does not require the AST node to be deserialized.
|
||||
operator bool() const { return Ptr != 0; }
|
||||
|
||||
/// \brief Whether this pointer is currently stored as an offset.
|
||||
bool isOffset() const { return Ptr & 0x01; }
|
||||
|
||||
/// \brief Retrieve the pointer to the AST node that this lazy pointer
|
||||
///
|
||||
/// \param Source the external AST source.
|
||||
///
|
||||
/// \returns a pointer to the AST node.
|
||||
T* get(ExternalASTSource *Source) const {
|
||||
if (isOffset()) {
|
||||
assert(Source &&
|
||||
"Cannot deserialize a lazy pointer without an AST source");
|
||||
Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
|
||||
}
|
||||
return reinterpret_cast<T*>(Ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a lazily-loaded vector of data.
|
||||
///
|
||||
/// The lazily-loaded vector of data contains data that is partially loaded
|
||||
/// from an external source and partially added by local translation. The
|
||||
/// items loaded from the external source are loaded lazily, when needed for
|
||||
/// iteration over the complete vector.
|
||||
template<typename T, typename Source,
|
||||
void (Source::*Loader)(SmallVectorImpl<T>&),
|
||||
unsigned LoadedStorage = 2, unsigned LocalStorage = 4>
|
||||
class LazyVector {
|
||||
SmallVector<T, LoadedStorage> Loaded;
|
||||
SmallVector<T, LocalStorage> Local;
|
||||
|
||||
public:
|
||||
// Iteration over the elements in the vector.
|
||||
class iterator {
|
||||
LazyVector *Self;
|
||||
|
||||
/// \brief Position within the vector..
|
||||
///
|
||||
/// In a complete iteration, the Position field walks the range [-M, N),
|
||||
/// where negative values are used to indicate elements
|
||||
/// loaded from the external source while non-negative values are used to
|
||||
/// indicate elements added via \c push_back().
|
||||
/// However, to provide iteration in source order (for, e.g., chained
|
||||
/// precompiled headers), dereferencing the iterator flips the negative
|
||||
/// values (corresponding to loaded entities), so that position -M
|
||||
/// corresponds to element 0 in the loaded entities vector, position -M+1
|
||||
/// corresponds to element 1 in the loaded entities vector, etc. This
|
||||
/// gives us a reasonably efficient, source-order walk.
|
||||
int Position;
|
||||
|
||||
friend class LazyVector;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef value_type& reference;
|
||||
typedef value_type* pointer;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef int difference_type;
|
||||
|
||||
iterator() : Self(0), Position(0) { }
|
||||
|
||||
iterator(LazyVector *Self, int Position)
|
||||
: Self(Self), Position(Position) { }
|
||||
|
||||
reference operator*() const {
|
||||
if (Position < 0)
|
||||
return Self->Loaded.end()[Position];
|
||||
return Self->Local[Position];
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
if (Position < 0)
|
||||
return &Self->Loaded.end()[Position];
|
||||
|
||||
return &Self->Local[Position];
|
||||
}
|
||||
|
||||
reference operator[](difference_type D) {
|
||||
return *(*this + D);
|
||||
}
|
||||
|
||||
iterator &operator++() {
|
||||
++Position;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator++(int) {
|
||||
iterator Prev(*this);
|
||||
++Position;
|
||||
return Prev;
|
||||
}
|
||||
|
||||
iterator &operator--() {
|
||||
--Position;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator--(int) {
|
||||
iterator Prev(*this);
|
||||
--Position;
|
||||
return Prev;
|
||||
}
|
||||
|
||||
friend bool operator==(const iterator &X, const iterator &Y) {
|
||||
return X.Position == Y.Position;
|
||||
}
|
||||
|
||||
friend bool operator!=(const iterator &X, const iterator &Y) {
|
||||
return X.Position != Y.Position;
|
||||
}
|
||||
|
||||
friend bool operator<(const iterator &X, const iterator &Y) {
|
||||
return X.Position < Y.Position;
|
||||
}
|
||||
|
||||
friend bool operator>(const iterator &X, const iterator &Y) {
|
||||
return X.Position > Y.Position;
|
||||
}
|
||||
|
||||
friend bool operator<=(const iterator &X, const iterator &Y) {
|
||||
return X.Position < Y.Position;
|
||||
}
|
||||
|
||||
friend bool operator>=(const iterator &X, const iterator &Y) {
|
||||
return X.Position > Y.Position;
|
||||
}
|
||||
|
||||
friend iterator& operator+=(iterator &X, difference_type D) {
|
||||
X.Position += D;
|
||||
return X;
|
||||
}
|
||||
|
||||
friend iterator& operator-=(iterator &X, difference_type D) {
|
||||
X.Position -= D;
|
||||
return X;
|
||||
}
|
||||
|
||||
friend iterator operator+(iterator X, difference_type D) {
|
||||
X.Position += D;
|
||||
return X;
|
||||
}
|
||||
|
||||
friend iterator operator+(difference_type D, iterator X) {
|
||||
X.Position += D;
|
||||
return X;
|
||||
}
|
||||
|
||||
friend difference_type operator-(const iterator &X, const iterator &Y) {
|
||||
return X.Position - Y.Position;
|
||||
}
|
||||
|
||||
friend iterator operator-(iterator X, difference_type D) {
|
||||
X.Position -= D;
|
||||
return X;
|
||||
}
|
||||
};
|
||||
friend class iterator;
|
||||
|
||||
iterator begin(Source *source, bool LocalOnly = false) {
|
||||
if (LocalOnly)
|
||||
return iterator(this, 0);
|
||||
|
||||
if (source)
|
||||
(source->*Loader)(Loaded);
|
||||
return iterator(this, -(int)Loaded.size());
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(this, Local.size());
|
||||
}
|
||||
|
||||
void push_back(const T& LocalValue) {
|
||||
Local.push_back(LocalValue);
|
||||
}
|
||||
|
||||
void erase(iterator From, iterator To) {
|
||||
if (From.Position < 0 && To.Position < 0) {
|
||||
Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position);
|
||||
return;
|
||||
}
|
||||
|
||||
if (From.Position < 0) {
|
||||
Loaded.erase(Loaded.end() + From.Position, Loaded.end());
|
||||
From = begin(0, true);
|
||||
}
|
||||
|
||||
Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A lazy pointer to a statement.
|
||||
typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
|
||||
LazyDeclStmtPtr;
|
||||
|
||||
/// \brief A lazy pointer to a declaration.
|
||||
typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
|
||||
LazyDeclPtr;
|
||||
|
||||
/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
|
||||
typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
|
||||
&ExternalASTSource::GetExternalCXXBaseSpecifiers>
|
||||
LazyCXXBaseSpecifiersPtr;
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
|
||||
124
thirdparty/clang/include/clang/AST/GlobalDecl.h
vendored
Normal file
124
thirdparty/clang/include/clang/AST/GlobalDecl.h
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
|
||||
// together with its type.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_GLOBALDECL_H
|
||||
#define LLVM_CLANG_AST_GLOBALDECL_H
|
||||
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// GlobalDecl - represents a global declaration. This can either be a
|
||||
/// CXXConstructorDecl and the constructor type (Base, Complete).
|
||||
/// a CXXDestructorDecl and the destructor type (Base, Complete) or
|
||||
/// a VarDecl, a FunctionDecl or a BlockDecl.
|
||||
class GlobalDecl {
|
||||
llvm::PointerIntPair<const Decl*, 2> Value;
|
||||
|
||||
void Init(const Decl *D) {
|
||||
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
|
||||
assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
|
||||
|
||||
Value.setPointer(D);
|
||||
}
|
||||
|
||||
public:
|
||||
GlobalDecl() {}
|
||||
|
||||
GlobalDecl(const VarDecl *D) { Init(D);}
|
||||
GlobalDecl(const FunctionDecl *D) { Init(D); }
|
||||
GlobalDecl(const BlockDecl *D) { Init(D); }
|
||||
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
|
||||
|
||||
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
|
||||
: Value(D, Type) {}
|
||||
GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
|
||||
: Value(D, Type) {}
|
||||
|
||||
GlobalDecl getCanonicalDecl() const {
|
||||
GlobalDecl CanonGD;
|
||||
CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
|
||||
CanonGD.Value.setInt(Value.getInt());
|
||||
|
||||
return CanonGD;
|
||||
}
|
||||
|
||||
const Decl *getDecl() const { return Value.getPointer(); }
|
||||
|
||||
CXXCtorType getCtorType() const {
|
||||
assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
|
||||
return static_cast<CXXCtorType>(Value.getInt());
|
||||
}
|
||||
|
||||
CXXDtorType getDtorType() const {
|
||||
assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
|
||||
return static_cast<CXXDtorType>(Value.getInt());
|
||||
}
|
||||
|
||||
friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
|
||||
return LHS.Value == RHS.Value;
|
||||
}
|
||||
|
||||
void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
|
||||
|
||||
static GlobalDecl getFromOpaquePtr(void *P) {
|
||||
GlobalDecl GD;
|
||||
GD.Value.setFromOpaqueValue(P);
|
||||
return GD;
|
||||
}
|
||||
|
||||
GlobalDecl getWithDecl(const Decl *D) {
|
||||
GlobalDecl Result(*this);
|
||||
Result.Value.setPointer(D);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
namespace llvm {
|
||||
template<class> struct DenseMapInfo;
|
||||
|
||||
template<> struct DenseMapInfo<clang::GlobalDecl> {
|
||||
static inline clang::GlobalDecl getEmptyKey() {
|
||||
return clang::GlobalDecl();
|
||||
}
|
||||
|
||||
static inline clang::GlobalDecl getTombstoneKey() {
|
||||
return clang::GlobalDecl::
|
||||
getFromOpaquePtr(reinterpret_cast<void*>(-1));
|
||||
}
|
||||
|
||||
static unsigned getHashValue(clang::GlobalDecl GD) {
|
||||
return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
|
||||
}
|
||||
|
||||
static bool isEqual(clang::GlobalDecl LHS,
|
||||
clang::GlobalDecl RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// GlobalDecl isn't *technically* a POD type. However, its copy constructor,
|
||||
// copy assignment operator, and destructor are all trivial.
|
||||
template <>
|
||||
struct isPodLike<clang::GlobalDecl> {
|
||||
static const bool value = true;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
38
thirdparty/clang/include/clang/AST/LambdaMangleContext.h
vendored
Normal file
38
thirdparty/clang/include/clang/AST/LambdaMangleContext.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
//===--- LambdaMangleContext.h - Context for mangling lambdas ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the LambdaMangleContext interface, which keeps track of
|
||||
// the Itanium C++ ABI mangling numbers for lambda expressions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H
|
||||
#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CXXMethodDecl;
|
||||
class FunctionProtoType;
|
||||
|
||||
/// \brief Keeps track of the mangled names of lambda expressions within a
|
||||
/// particular context.
|
||||
class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> {
|
||||
llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers;
|
||||
|
||||
public:
|
||||
/// \brief Retrieve the mangling number of a new lambda expression with the
|
||||
/// given call operator within this lambda context.
|
||||
unsigned getManglingNumber(CXXMethodDecl *CallOperator);
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
#endif
|
||||
164
thirdparty/clang/include/clang/AST/Mangle.h
vendored
Normal file
164
thirdparty/clang/include/clang/AST/Mangle.h
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the C++ name mangling interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_MANGLE_H
|
||||
#define LLVM_CLANG_AST_MANGLE_H
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class BlockDecl;
|
||||
class CXXConstructorDecl;
|
||||
class CXXDestructorDecl;
|
||||
class CXXMethodDecl;
|
||||
class FunctionDecl;
|
||||
class NamedDecl;
|
||||
class ObjCMethodDecl;
|
||||
class VarDecl;
|
||||
struct ThisAdjustment;
|
||||
struct ThunkInfo;
|
||||
|
||||
/// MangleBuffer - a convenient class for storing a name which is
|
||||
/// either the result of a mangling or is a constant string with
|
||||
/// external memory ownership.
|
||||
class MangleBuffer {
|
||||
public:
|
||||
void setString(StringRef Ref) {
|
||||
String = Ref;
|
||||
}
|
||||
|
||||
SmallVectorImpl<char> &getBuffer() {
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
StringRef getString() const {
|
||||
if (!String.empty()) return String;
|
||||
return Buffer.str();
|
||||
}
|
||||
|
||||
operator StringRef() const {
|
||||
return getString();
|
||||
}
|
||||
|
||||
private:
|
||||
StringRef String;
|
||||
SmallString<256> Buffer;
|
||||
};
|
||||
|
||||
/// MangleContext - Context for tracking state which persists across multiple
|
||||
/// calls to the C++ name mangler.
|
||||
class MangleContext {
|
||||
virtual void anchor();
|
||||
|
||||
ASTContext &Context;
|
||||
DiagnosticsEngine &Diags;
|
||||
|
||||
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
|
||||
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
|
||||
|
||||
public:
|
||||
explicit MangleContext(ASTContext &Context,
|
||||
DiagnosticsEngine &Diags)
|
||||
: Context(Context), Diags(Diags) { }
|
||||
|
||||
virtual ~MangleContext() { }
|
||||
|
||||
ASTContext &getASTContext() const { return Context; }
|
||||
|
||||
DiagnosticsEngine &getDiags() const { return Diags; }
|
||||
|
||||
virtual void startNewFunction() { LocalBlockIds.clear(); }
|
||||
|
||||
unsigned getBlockId(const BlockDecl *BD, bool Local) {
|
||||
llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
|
||||
= Local? LocalBlockIds : GlobalBlockIds;
|
||||
std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
|
||||
Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
|
||||
return Result.first->second;
|
||||
}
|
||||
|
||||
/// @name Mangler Entry Points
|
||||
/// @{
|
||||
|
||||
virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
|
||||
virtual void mangleName(const NamedDecl *D, raw_ostream &)=0;
|
||||
virtual void mangleThunk(const CXXMethodDecl *MD,
|
||||
const ThunkInfo &Thunk,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
||||
const ThisAdjustment &ThisAdjustment,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleReferenceTemporary(const VarDecl *D,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleCXXVTable(const CXXRecordDecl *RD,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleCXXVTT(const CXXRecordDecl *RD,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
||||
const CXXRecordDecl *Type,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
|
||||
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
|
||||
virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
||||
raw_ostream &) = 0;
|
||||
|
||||
void mangleGlobalBlock(const BlockDecl *BD,
|
||||
const NamedDecl *ID,
|
||||
raw_ostream &Out);
|
||||
void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
|
||||
const BlockDecl *BD, raw_ostream &Out);
|
||||
void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
|
||||
const BlockDecl *BD, raw_ostream &Out);
|
||||
void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
|
||||
raw_ostream &Out);
|
||||
// Do the right thing.
|
||||
void mangleBlock(const BlockDecl *BD, raw_ostream &Out,
|
||||
const NamedDecl *ID=0);
|
||||
|
||||
void mangleObjCMethodName(const ObjCMethodDecl *MD,
|
||||
raw_ostream &);
|
||||
|
||||
// This is pretty lame.
|
||||
virtual void mangleItaniumGuardVariable(const VarDecl *D,
|
||||
raw_ostream &) {
|
||||
llvm_unreachable("Target does not support mangling guard variables");
|
||||
}
|
||||
// FIXME: Revisit this once we know what we need to do for MSVC compatibility.
|
||||
virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
|
||||
raw_ostream &) {
|
||||
llvm_unreachable("Target does not support mangling thread_local variables");
|
||||
}
|
||||
virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
|
||||
raw_ostream &) {
|
||||
llvm_unreachable("Target does not support mangling thread_local variables");
|
||||
}
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
MangleContext *createItaniumMangleContext(ASTContext &Context,
|
||||
DiagnosticsEngine &Diags);
|
||||
MangleContext *createMicrosoftMangleContext(ASTContext &Context,
|
||||
DiagnosticsEngine &Diags);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
220
thirdparty/clang/include/clang/AST/NSAPI.h
vendored
Normal file
220
thirdparty/clang/include/clang/AST/NSAPI.h
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
//===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_NSAPI_H
|
||||
#define LLVM_CLANG_AST_NSAPI_H
|
||||
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class QualType;
|
||||
class Expr;
|
||||
|
||||
// \brief Provides info and caches identifiers/selectors for NSFoundation API.
|
||||
class NSAPI {
|
||||
public:
|
||||
explicit NSAPI(ASTContext &Ctx);
|
||||
|
||||
ASTContext &getASTContext() const { return Ctx; }
|
||||
|
||||
enum NSClassIdKindKind {
|
||||
ClassId_NSObject,
|
||||
ClassId_NSString,
|
||||
ClassId_NSArray,
|
||||
ClassId_NSMutableArray,
|
||||
ClassId_NSDictionary,
|
||||
ClassId_NSMutableDictionary,
|
||||
ClassId_NSNumber
|
||||
};
|
||||
static const unsigned NumClassIds = 7;
|
||||
|
||||
enum NSStringMethodKind {
|
||||
NSStr_stringWithString,
|
||||
NSStr_stringWithUTF8String,
|
||||
NSStr_stringWithCStringEncoding,
|
||||
NSStr_stringWithCString,
|
||||
NSStr_initWithString
|
||||
};
|
||||
static const unsigned NumNSStringMethods = 5;
|
||||
|
||||
IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
|
||||
|
||||
/// \brief The Objective-C NSString selectors.
|
||||
Selector getNSStringSelector(NSStringMethodKind MK) const;
|
||||
|
||||
/// \brief Return NSStringMethodKind if \param Sel is such a selector.
|
||||
Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
|
||||
|
||||
/// \brief Returns true if the expression \param E is a reference of
|
||||
/// "NSUTF8StringEncoding" enum constant.
|
||||
bool isNSUTF8StringEncodingConstant(const Expr *E) const {
|
||||
return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the expression \param E is a reference of
|
||||
/// "NSASCIIStringEncoding" enum constant.
|
||||
bool isNSASCIIStringEncodingConstant(const Expr *E) const {
|
||||
return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId);
|
||||
}
|
||||
|
||||
/// \brief Enumerates the NSArray methods used to generate literals.
|
||||
enum NSArrayMethodKind {
|
||||
NSArr_array,
|
||||
NSArr_arrayWithArray,
|
||||
NSArr_arrayWithObject,
|
||||
NSArr_arrayWithObjects,
|
||||
NSArr_arrayWithObjectsCount,
|
||||
NSArr_initWithArray,
|
||||
NSArr_initWithObjects,
|
||||
NSArr_objectAtIndex,
|
||||
NSMutableArr_replaceObjectAtIndex
|
||||
};
|
||||
static const unsigned NumNSArrayMethods = 9;
|
||||
|
||||
/// \brief The Objective-C NSArray selectors.
|
||||
Selector getNSArraySelector(NSArrayMethodKind MK) const;
|
||||
|
||||
/// \brief Return NSArrayMethodKind if \p Sel is such a selector.
|
||||
Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
|
||||
|
||||
/// \brief Enumerates the NSDictionary methods used to generate literals.
|
||||
enum NSDictionaryMethodKind {
|
||||
NSDict_dictionary,
|
||||
NSDict_dictionaryWithDictionary,
|
||||
NSDict_dictionaryWithObjectForKey,
|
||||
NSDict_dictionaryWithObjectsForKeys,
|
||||
NSDict_dictionaryWithObjectsForKeysCount,
|
||||
NSDict_dictionaryWithObjectsAndKeys,
|
||||
NSDict_initWithDictionary,
|
||||
NSDict_initWithObjectsAndKeys,
|
||||
NSDict_initWithObjectsForKeys,
|
||||
NSDict_objectForKey,
|
||||
NSMutableDict_setObjectForKey
|
||||
};
|
||||
static const unsigned NumNSDictionaryMethods = 11;
|
||||
|
||||
/// \brief The Objective-C NSDictionary selectors.
|
||||
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
|
||||
|
||||
/// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
|
||||
Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
|
||||
|
||||
/// \brief Returns selector for "objectForKeyedSubscript:".
|
||||
Selector getObjectForKeyedSubscriptSelector() const {
|
||||
return getOrInitSelector(StringRef("objectForKeyedSubscript"),
|
||||
objectForKeyedSubscriptSel);
|
||||
}
|
||||
|
||||
/// \brief Returns selector for "objectAtIndexedSubscript:".
|
||||
Selector getObjectAtIndexedSubscriptSelector() const {
|
||||
return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
|
||||
objectAtIndexedSubscriptSel);
|
||||
}
|
||||
|
||||
/// \brief Returns selector for "setObject:forKeyedSubscript".
|
||||
Selector getSetObjectForKeyedSubscriptSelector() const {
|
||||
StringRef Ids[] = { "setObject", "forKeyedSubscript" };
|
||||
return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
|
||||
}
|
||||
|
||||
/// \brief Returns selector for "setObject:atIndexedSubscript".
|
||||
Selector getSetObjectAtIndexedSubscriptSelector() const {
|
||||
StringRef Ids[] = { "setObject", "atIndexedSubscript" };
|
||||
return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
|
||||
}
|
||||
|
||||
/// \brief Returns selector for "isEqual:".
|
||||
Selector getIsEqualSelector() const {
|
||||
return getOrInitSelector(StringRef("isEqual"), isEqualSel);
|
||||
}
|
||||
|
||||
/// \brief Enumerates the NSNumber methods used to generate literals.
|
||||
enum NSNumberLiteralMethodKind {
|
||||
NSNumberWithChar,
|
||||
NSNumberWithUnsignedChar,
|
||||
NSNumberWithShort,
|
||||
NSNumberWithUnsignedShort,
|
||||
NSNumberWithInt,
|
||||
NSNumberWithUnsignedInt,
|
||||
NSNumberWithLong,
|
||||
NSNumberWithUnsignedLong,
|
||||
NSNumberWithLongLong,
|
||||
NSNumberWithUnsignedLongLong,
|
||||
NSNumberWithFloat,
|
||||
NSNumberWithDouble,
|
||||
NSNumberWithBool,
|
||||
NSNumberWithInteger,
|
||||
NSNumberWithUnsignedInteger
|
||||
};
|
||||
static const unsigned NumNSNumberLiteralMethods = 15;
|
||||
|
||||
/// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
|
||||
/// \param Instance if true it will return the selector for the init* method
|
||||
/// otherwise it will return the selector for the number* method.
|
||||
Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
|
||||
bool Instance) const;
|
||||
|
||||
bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
|
||||
Selector Sel) const {
|
||||
return Sel == getNSNumberLiteralSelector(MK, false) ||
|
||||
Sel == getNSNumberLiteralSelector(MK, true);
|
||||
}
|
||||
|
||||
/// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector.
|
||||
Optional<NSNumberLiteralMethodKind>
|
||||
getNSNumberLiteralMethodKind(Selector Sel) const;
|
||||
|
||||
/// \brief Determine the appropriate NSNumber factory method kind for a
|
||||
/// literal of the given type.
|
||||
Optional<NSNumberLiteralMethodKind>
|
||||
getNSNumberFactoryMethodKind(QualType T) const;
|
||||
|
||||
/// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
|
||||
bool isObjCBOOLType(QualType T) const;
|
||||
/// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
|
||||
bool isObjCNSIntegerType(QualType T) const;
|
||||
/// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
|
||||
bool isObjCNSUIntegerType(QualType T) const;
|
||||
|
||||
private:
|
||||
bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
|
||||
bool isObjCEnumerator(const Expr *E,
|
||||
StringRef name, IdentifierInfo *&II) const;
|
||||
Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
|
||||
|
||||
ASTContext &Ctx;
|
||||
|
||||
mutable IdentifierInfo *ClassIds[NumClassIds];
|
||||
|
||||
mutable Selector NSStringSelectors[NumNSStringMethods];
|
||||
|
||||
/// \brief The selectors for Objective-C NSArray methods.
|
||||
mutable Selector NSArraySelectors[NumNSArrayMethods];
|
||||
|
||||
/// \brief The selectors for Objective-C NSDictionary methods.
|
||||
mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
|
||||
|
||||
/// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
|
||||
mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
|
||||
mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
|
||||
|
||||
mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
|
||||
setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
|
||||
isEqualSel;
|
||||
|
||||
mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
|
||||
mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_NSAPI_H
|
||||
481
thirdparty/clang/include/clang/AST/NestedNameSpecifier.h
vendored
Normal file
481
thirdparty/clang/include/clang/AST/NestedNameSpecifier.h
vendored
Normal file
@@ -0,0 +1,481 @@
|
||||
//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the NestedNameSpecifier class, which represents
|
||||
// a C++ nested-name-specifier.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
|
||||
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class NamespaceAliasDecl;
|
||||
class NamespaceDecl;
|
||||
class IdentifierInfo;
|
||||
struct PrintingPolicy;
|
||||
class Type;
|
||||
class TypeLoc;
|
||||
class LangOptions;
|
||||
|
||||
/// \brief Represents a C++ nested name specifier, such as
|
||||
/// "\::std::vector<int>::".
|
||||
///
|
||||
/// C++ nested name specifiers are the prefixes to qualified
|
||||
/// namespaces. For example, "foo::" in "foo::x" is a nested name
|
||||
/// specifier. Nested name specifiers are made up of a sequence of
|
||||
/// specifiers, each of which can be a namespace, type, identifier
|
||||
/// (for dependent names), decltype specifier, or the global specifier ('::').
|
||||
/// The last two specifiers can only appear at the start of a
|
||||
/// nested-namespace-specifier.
|
||||
class NestedNameSpecifier : public llvm::FoldingSetNode {
|
||||
|
||||
/// \brief Enumeration describing
|
||||
enum StoredSpecifierKind {
|
||||
StoredIdentifier = 0,
|
||||
StoredNamespaceOrAlias = 1,
|
||||
StoredTypeSpec = 2,
|
||||
StoredTypeSpecWithTemplate = 3
|
||||
};
|
||||
|
||||
/// \brief The nested name specifier that precedes this nested name
|
||||
/// specifier.
|
||||
///
|
||||
/// The pointer is the nested-name-specifier that precedes this
|
||||
/// one. The integer stores one of the first four values of type
|
||||
/// SpecifierKind.
|
||||
llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
|
||||
|
||||
/// \brief The last component in the nested name specifier, which
|
||||
/// can be an identifier, a declaration, or a type.
|
||||
///
|
||||
/// When the pointer is NULL, this specifier represents the global
|
||||
/// specifier '::'. Otherwise, the pointer is one of
|
||||
/// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
|
||||
/// specifier as encoded within the prefix.
|
||||
void* Specifier;
|
||||
|
||||
public:
|
||||
/// \brief The kind of specifier that completes this nested name
|
||||
/// specifier.
|
||||
enum SpecifierKind {
|
||||
/// \brief An identifier, stored as an IdentifierInfo*.
|
||||
Identifier,
|
||||
/// \brief A namespace, stored as a NamespaceDecl*.
|
||||
Namespace,
|
||||
/// \brief A namespace alias, stored as a NamespaceAliasDecl*.
|
||||
NamespaceAlias,
|
||||
/// \brief A type, stored as a Type*.
|
||||
TypeSpec,
|
||||
/// \brief A type that was preceded by the 'template' keyword,
|
||||
/// stored as a Type*.
|
||||
TypeSpecWithTemplate,
|
||||
/// \brief The global specifier '::'. There is no stored value.
|
||||
Global
|
||||
};
|
||||
|
||||
private:
|
||||
/// \brief Builds the global specifier.
|
||||
NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
|
||||
|
||||
/// \brief Copy constructor used internally to clone nested name
|
||||
/// specifiers.
|
||||
NestedNameSpecifier(const NestedNameSpecifier &Other)
|
||||
: llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
|
||||
Specifier(Other.Specifier) {
|
||||
}
|
||||
|
||||
void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
/// \brief Either find or insert the given nested name specifier
|
||||
/// mockup in the given context.
|
||||
static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
|
||||
const NestedNameSpecifier &Mockup);
|
||||
|
||||
public:
|
||||
/// \brief Builds a specifier combining a prefix and an identifier.
|
||||
///
|
||||
/// The prefix must be dependent, since nested name specifiers
|
||||
/// referencing an identifier are only permitted when the identifier
|
||||
/// cannot be resolved.
|
||||
static NestedNameSpecifier *Create(const ASTContext &Context,
|
||||
NestedNameSpecifier *Prefix,
|
||||
IdentifierInfo *II);
|
||||
|
||||
/// \brief Builds a nested name specifier that names a namespace.
|
||||
static NestedNameSpecifier *Create(const ASTContext &Context,
|
||||
NestedNameSpecifier *Prefix,
|
||||
const NamespaceDecl *NS);
|
||||
|
||||
/// \brief Builds a nested name specifier that names a namespace alias.
|
||||
static NestedNameSpecifier *Create(const ASTContext &Context,
|
||||
NestedNameSpecifier *Prefix,
|
||||
NamespaceAliasDecl *Alias);
|
||||
|
||||
/// \brief Builds a nested name specifier that names a type.
|
||||
static NestedNameSpecifier *Create(const ASTContext &Context,
|
||||
NestedNameSpecifier *Prefix,
|
||||
bool Template, const Type *T);
|
||||
|
||||
/// \brief Builds a specifier that consists of just an identifier.
|
||||
///
|
||||
/// The nested-name-specifier is assumed to be dependent, but has no
|
||||
/// prefix because the prefix is implied by something outside of the
|
||||
/// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
|
||||
/// type.
|
||||
static NestedNameSpecifier *Create(const ASTContext &Context,
|
||||
IdentifierInfo *II);
|
||||
|
||||
/// \brief Returns the nested name specifier representing the global
|
||||
/// scope.
|
||||
static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
|
||||
|
||||
/// \brief Return the prefix of this nested name specifier.
|
||||
///
|
||||
/// The prefix contains all of the parts of the nested name
|
||||
/// specifier that preced this current specifier. For example, for a
|
||||
/// nested name specifier that represents "foo::bar::", the current
|
||||
/// specifier will contain "bar::" and the prefix will contain
|
||||
/// "foo::".
|
||||
NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
|
||||
|
||||
/// \brief Determine what kind of nested name specifier is stored.
|
||||
SpecifierKind getKind() const;
|
||||
|
||||
/// \brief Retrieve the identifier stored in this nested name
|
||||
/// specifier.
|
||||
IdentifierInfo *getAsIdentifier() const {
|
||||
if (Prefix.getInt() == StoredIdentifier)
|
||||
return (IdentifierInfo *)Specifier;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the namespace stored in this nested name
|
||||
/// specifier.
|
||||
NamespaceDecl *getAsNamespace() const;
|
||||
|
||||
/// \brief Retrieve the namespace alias stored in this nested name
|
||||
/// specifier.
|
||||
NamespaceAliasDecl *getAsNamespaceAlias() const;
|
||||
|
||||
/// \brief Retrieve the type stored in this nested name specifier.
|
||||
const Type *getAsType() const {
|
||||
if (Prefix.getInt() == StoredTypeSpec ||
|
||||
Prefix.getInt() == StoredTypeSpecWithTemplate)
|
||||
return (const Type *)Specifier;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Whether this nested name specifier refers to a dependent
|
||||
/// type or not.
|
||||
bool isDependent() const;
|
||||
|
||||
/// \brief Whether this nested name specifier involves a template
|
||||
/// parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Whether this nested-name-specifier contains an unexpanded
|
||||
/// parameter pack (for C++11 variadic templates).
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
||||
/// \brief Print this nested name specifier to the given output
|
||||
/// stream.
|
||||
void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) const {
|
||||
ID.AddPointer(Prefix.getOpaqueValue());
|
||||
ID.AddPointer(Specifier);
|
||||
}
|
||||
|
||||
/// \brief Dump the nested name specifier to standard output to aid
|
||||
/// in debugging.
|
||||
void dump(const LangOptions &LO);
|
||||
};
|
||||
|
||||
/// \brief A C++ nested-name-specifier augmented with source location
|
||||
/// information.
|
||||
class NestedNameSpecifierLoc {
|
||||
NestedNameSpecifier *Qualifier;
|
||||
void *Data;
|
||||
|
||||
/// \brief Determines the data length for the last component in the
|
||||
/// given nested-name-specifier.
|
||||
static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
|
||||
|
||||
/// \brief Determines the data length for the entire
|
||||
/// nested-name-specifier.
|
||||
static unsigned getDataLength(NestedNameSpecifier *Qualifier);
|
||||
|
||||
public:
|
||||
/// \brief Construct an empty nested-name-specifier.
|
||||
NestedNameSpecifierLoc() : Qualifier(0), Data(0) { }
|
||||
|
||||
/// \brief Construct a nested-name-specifier with source location information
|
||||
/// from
|
||||
NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
|
||||
: Qualifier(Qualifier), Data(Data) { }
|
||||
|
||||
/// \brief Evalutes true when this nested-name-specifier location is
|
||||
/// non-empty.
|
||||
operator bool() const { return Qualifier; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier to which this instance
|
||||
/// refers.
|
||||
NestedNameSpecifier *getNestedNameSpecifier() const {
|
||||
return Qualifier;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the opaque pointer that refers to source-location data.
|
||||
void *getOpaqueData() const { return Data; }
|
||||
|
||||
/// \brief Retrieve the source range covering the entirety of this
|
||||
/// nested-name-specifier.
|
||||
///
|
||||
/// For example, if this instance refers to a nested-name-specifier
|
||||
/// \c \::std::vector<int>::, the returned source range would cover
|
||||
/// from the initial '::' to the last '::'.
|
||||
SourceRange getSourceRange() const LLVM_READONLY;
|
||||
|
||||
/// \brief Retrieve the source range covering just the last part of
|
||||
/// this nested-name-specifier, not including the prefix.
|
||||
///
|
||||
/// For example, if this instance refers to a nested-name-specifier
|
||||
/// \c \::std::vector<int>::, the returned source range would cover
|
||||
/// from "vector" to the last '::'.
|
||||
SourceRange getLocalSourceRange() const;
|
||||
|
||||
/// \brief Retrieve the location of the beginning of this
|
||||
/// nested-name-specifier.
|
||||
SourceLocation getBeginLoc() const {
|
||||
return getSourceRange().getBegin();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the end of this
|
||||
/// nested-name-specifier.
|
||||
SourceLocation getEndLoc() const {
|
||||
return getSourceRange().getEnd();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the beginning of this
|
||||
/// component of the nested-name-specifier.
|
||||
SourceLocation getLocalBeginLoc() const {
|
||||
return getLocalSourceRange().getBegin();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the end of this component of the
|
||||
/// nested-name-specifier.
|
||||
SourceLocation getLocalEndLoc() const {
|
||||
return getLocalSourceRange().getEnd();
|
||||
}
|
||||
|
||||
/// \brief Return the prefix of this nested-name-specifier.
|
||||
///
|
||||
/// For example, if this instance refers to a nested-name-specifier
|
||||
/// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
|
||||
/// returned prefix may be empty, if this is the first component of
|
||||
/// the nested-name-specifier.
|
||||
NestedNameSpecifierLoc getPrefix() const {
|
||||
if (!Qualifier)
|
||||
return *this;
|
||||
|
||||
return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
|
||||
}
|
||||
|
||||
/// \brief For a nested-name-specifier that refers to a type,
|
||||
/// retrieve the type with source-location information.
|
||||
TypeLoc getTypeLoc() const;
|
||||
|
||||
/// \brief Determines the data length for the entire
|
||||
/// nested-name-specifier.
|
||||
unsigned getDataLength() const { return getDataLength(Qualifier); }
|
||||
|
||||
friend bool operator==(NestedNameSpecifierLoc X,
|
||||
NestedNameSpecifierLoc Y) {
|
||||
return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
|
||||
}
|
||||
|
||||
friend bool operator!=(NestedNameSpecifierLoc X,
|
||||
NestedNameSpecifierLoc Y) {
|
||||
return !(X == Y);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Class that aids in the construction of nested-name-specifiers along
|
||||
/// with source-location information for all of the components of the
|
||||
/// nested-name-specifier.
|
||||
class NestedNameSpecifierLocBuilder {
|
||||
/// \brief The current representation of the nested-name-specifier we're
|
||||
/// building.
|
||||
NestedNameSpecifier *Representation;
|
||||
|
||||
/// \brief Buffer used to store source-location information for the
|
||||
/// nested-name-specifier.
|
||||
///
|
||||
/// Note that we explicitly manage the buffer (rather than using a
|
||||
/// SmallVector) because \c Declarator expects it to be possible to memcpy()
|
||||
/// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
|
||||
char *Buffer;
|
||||
|
||||
/// \brief The size of the buffer used to store source-location information
|
||||
/// for the nested-name-specifier.
|
||||
unsigned BufferSize;
|
||||
|
||||
/// \brief The capacity of the buffer used to store source-location
|
||||
/// information for the nested-name-specifier.
|
||||
unsigned BufferCapacity;
|
||||
|
||||
public:
|
||||
NestedNameSpecifierLocBuilder()
|
||||
: Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
|
||||
|
||||
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
|
||||
|
||||
NestedNameSpecifierLocBuilder &
|
||||
operator=(const NestedNameSpecifierLocBuilder &Other);
|
||||
|
||||
~NestedNameSpecifierLocBuilder() {
|
||||
if (BufferCapacity)
|
||||
free(Buffer);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the representation of the nested-name-specifier.
|
||||
NestedNameSpecifier *getRepresentation() const { return Representation; }
|
||||
|
||||
/// \brief Extend the current nested-name-specifier by another
|
||||
/// nested-name-specifier component of the form 'type::'.
|
||||
///
|
||||
/// \param Context The AST context in which this nested-name-specifier
|
||||
/// resides.
|
||||
///
|
||||
/// \param TemplateKWLoc The location of the 'template' keyword, if present.
|
||||
///
|
||||
/// \param TL The TypeLoc that describes the type preceding the '::'.
|
||||
///
|
||||
/// \param ColonColonLoc The location of the trailing '::'.
|
||||
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
|
||||
SourceLocation ColonColonLoc);
|
||||
|
||||
/// \brief Extend the current nested-name-specifier by another
|
||||
/// nested-name-specifier component of the form 'identifier::'.
|
||||
///
|
||||
/// \param Context The AST context in which this nested-name-specifier
|
||||
/// resides.
|
||||
///
|
||||
/// \param Identifier The identifier.
|
||||
///
|
||||
/// \param IdentifierLoc The location of the identifier.
|
||||
///
|
||||
/// \param ColonColonLoc The location of the trailing '::'.
|
||||
void Extend(ASTContext &Context, IdentifierInfo *Identifier,
|
||||
SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
|
||||
|
||||
/// \brief Extend the current nested-name-specifier by another
|
||||
/// nested-name-specifier component of the form 'namespace::'.
|
||||
///
|
||||
/// \param Context The AST context in which this nested-name-specifier
|
||||
/// resides.
|
||||
///
|
||||
/// \param Namespace The namespace.
|
||||
///
|
||||
/// \param NamespaceLoc The location of the namespace name.
|
||||
///
|
||||
/// \param ColonColonLoc The location of the trailing '::'.
|
||||
void Extend(ASTContext &Context, NamespaceDecl *Namespace,
|
||||
SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
|
||||
|
||||
/// \brief Extend the current nested-name-specifier by another
|
||||
/// nested-name-specifier component of the form 'namespace-alias::'.
|
||||
///
|
||||
/// \param Context The AST context in which this nested-name-specifier
|
||||
/// resides.
|
||||
///
|
||||
/// \param Alias The namespace alias.
|
||||
///
|
||||
/// \param AliasLoc The location of the namespace alias
|
||||
/// name.
|
||||
///
|
||||
/// \param ColonColonLoc The location of the trailing '::'.
|
||||
void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
|
||||
SourceLocation AliasLoc, SourceLocation ColonColonLoc);
|
||||
|
||||
/// \brief Turn this (empty) nested-name-specifier into the global
|
||||
/// nested-name-specifier '::'.
|
||||
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
|
||||
|
||||
/// \brief Make a new nested-name-specifier from incomplete source-location
|
||||
/// information.
|
||||
///
|
||||
/// This routine should be used very, very rarely, in cases where we
|
||||
/// need to synthesize a nested-name-specifier. Most code should instead use
|
||||
/// \c Adopt() with a proper \c NestedNameSpecifierLoc.
|
||||
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
|
||||
SourceRange R);
|
||||
|
||||
/// \brief Adopt an existing nested-name-specifier (with source-range
|
||||
/// information).
|
||||
void Adopt(NestedNameSpecifierLoc Other);
|
||||
|
||||
/// \brief Retrieve the source range covered by this nested-name-specifier.
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
|
||||
}
|
||||
|
||||
/// \brief Retrieve a nested-name-specifier with location information,
|
||||
/// copied into the given AST context.
|
||||
///
|
||||
/// \param Context The context into which this nested-name-specifier will be
|
||||
/// copied.
|
||||
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
|
||||
|
||||
/// \brief Retrieve a nested-name-specifier with location
|
||||
/// information based on the information in this builder.
|
||||
///
|
||||
/// This loc will contain references to the builder's internal data and may
|
||||
/// be invalidated by any change to the builder.
|
||||
NestedNameSpecifierLoc getTemporary() const {
|
||||
return NestedNameSpecifierLoc(Representation, Buffer);
|
||||
}
|
||||
|
||||
/// \brief Clear out this builder, and prepare it to build another
|
||||
/// nested-name-specifier with source-location information.
|
||||
void Clear() {
|
||||
Representation = 0;
|
||||
BufferSize = 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the underlying buffer.
|
||||
///
|
||||
/// \returns A pair containing a pointer to the buffer of source-location
|
||||
/// data and the size of the source-location data that resides in that
|
||||
/// buffer.
|
||||
std::pair<char *, unsigned> getBuffer() const {
|
||||
return std::make_pair(Buffer, BufferSize);
|
||||
}
|
||||
};
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending
|
||||
/// NestedNameSpecifiers into a diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
NestedNameSpecifier *NNS) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
|
||||
DiagnosticsEngine::ak_nestednamespec);
|
||||
return DB;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
352
thirdparty/clang/include/clang/AST/OperationKinds.h
vendored
Normal file
352
thirdparty/clang/include/clang/AST/OperationKinds.h
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
//===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file enumerates the different kinds of operations that can be
|
||||
// performed by various expressions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_OPERATION_KINDS_H
|
||||
#define LLVM_CLANG_AST_OPERATION_KINDS_H
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// CastKind - The kind of operation required for a conversion.
|
||||
enum CastKind {
|
||||
/// CK_Dependent - A conversion which cannot yet be analyzed because
|
||||
/// either the expression or target type is dependent. These are
|
||||
/// created only for explicit casts; dependent ASTs aren't required
|
||||
/// to even approximately type-check.
|
||||
/// (T*) malloc(sizeof(T))
|
||||
/// reinterpret_cast<intptr_t>(A<T>::alloc());
|
||||
CK_Dependent,
|
||||
|
||||
/// CK_BitCast - A conversion which causes a bit pattern of one type
|
||||
/// to be reinterpreted as a bit pattern of another type. Generally
|
||||
/// the operands must have equivalent size and unrelated types.
|
||||
///
|
||||
/// The pointer conversion char* -> int* is a bitcast. A conversion
|
||||
/// from any pointer type to a C pointer type is a bitcast unless
|
||||
/// it's actually BaseToDerived or DerivedToBase. A conversion to a
|
||||
/// block pointer or ObjC pointer type is a bitcast only if the
|
||||
/// operand has the same type kind; otherwise, it's one of the
|
||||
/// specialized casts below.
|
||||
///
|
||||
/// Vector coercions are bitcasts.
|
||||
CK_BitCast,
|
||||
|
||||
/// CK_LValueBitCast - A conversion which reinterprets the address of
|
||||
/// an l-value as an l-value of a different kind. Used for
|
||||
/// reinterpret_casts of l-value expressions to reference types.
|
||||
/// bool b; reinterpret_cast<char&>(b) = 'a';
|
||||
CK_LValueBitCast,
|
||||
|
||||
/// CK_LValueToRValue - A conversion which causes the extraction of
|
||||
/// an r-value from the operand gl-value. The result of an r-value
|
||||
/// conversion is always unqualified.
|
||||
CK_LValueToRValue,
|
||||
|
||||
/// CK_NoOp - A conversion which does not affect the type other than
|
||||
/// (possibly) adding qualifiers.
|
||||
/// int -> int
|
||||
/// char** -> const char * const *
|
||||
CK_NoOp,
|
||||
|
||||
/// CK_BaseToDerived - A conversion from a C++ class pointer/reference
|
||||
/// to a derived class pointer/reference.
|
||||
/// B *b = static_cast<B*>(a);
|
||||
CK_BaseToDerived,
|
||||
|
||||
/// CK_DerivedToBase - A conversion from a C++ class pointer
|
||||
/// to a base class pointer.
|
||||
/// A *a = new B();
|
||||
CK_DerivedToBase,
|
||||
|
||||
/// CK_UncheckedDerivedToBase - A conversion from a C++ class
|
||||
/// pointer/reference to a base class that can assume that the
|
||||
/// derived pointer is not null.
|
||||
/// const A &a = B();
|
||||
/// b->method_from_a();
|
||||
CK_UncheckedDerivedToBase,
|
||||
|
||||
/// CK_Dynamic - A C++ dynamic_cast.
|
||||
CK_Dynamic,
|
||||
|
||||
/// CK_ToUnion - The GCC cast-to-union extension.
|
||||
/// int -> union { int x; float y; }
|
||||
/// float -> union { int x; float y; }
|
||||
CK_ToUnion,
|
||||
|
||||
/// CK_ArrayToPointerDecay - Array to pointer decay.
|
||||
/// int[10] -> int*
|
||||
/// char[5][6] -> char(*)[6]
|
||||
CK_ArrayToPointerDecay,
|
||||
|
||||
/// CK_FunctionToPointerDecay - Function to pointer decay.
|
||||
/// void(int) -> void(*)(int)
|
||||
CK_FunctionToPointerDecay,
|
||||
|
||||
/// CK_NullToPointer - Null pointer constant to pointer, ObjC
|
||||
/// pointer, or block pointer.
|
||||
/// (void*) 0
|
||||
/// void (^block)() = 0;
|
||||
CK_NullToPointer,
|
||||
|
||||
/// CK_NullToMemberPointer - Null pointer constant to member pointer.
|
||||
/// int A::*mptr = 0;
|
||||
/// int (A::*fptr)(int) = nullptr;
|
||||
CK_NullToMemberPointer,
|
||||
|
||||
/// CK_BaseToDerivedMemberPointer - Member pointer in base class to
|
||||
/// member pointer in derived class.
|
||||
/// int B::*mptr = &A::member;
|
||||
CK_BaseToDerivedMemberPointer,
|
||||
|
||||
/// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
|
||||
/// member pointer in base class.
|
||||
/// int A::*mptr = static_cast<int A::*>(&B::member);
|
||||
CK_DerivedToBaseMemberPointer,
|
||||
|
||||
/// CK_MemberPointerToBoolean - Member pointer to boolean. A check
|
||||
/// against the null member pointer.
|
||||
CK_MemberPointerToBoolean,
|
||||
|
||||
/// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a
|
||||
/// different kind of member pointer. C++ forbids this from
|
||||
/// crossing between function and object types, but otherwise does
|
||||
/// not restrict it. However, the only operation that is permitted
|
||||
/// on a "punned" member pointer is casting it back to the original
|
||||
/// type, which is required to be a lossless operation (although
|
||||
/// many ABIs do not guarantee this on all possible intermediate types).
|
||||
CK_ReinterpretMemberPointer,
|
||||
|
||||
/// CK_UserDefinedConversion - Conversion using a user defined type
|
||||
/// conversion function.
|
||||
/// struct A { operator int(); }; int i = int(A());
|
||||
CK_UserDefinedConversion,
|
||||
|
||||
/// CK_ConstructorConversion - Conversion by constructor.
|
||||
/// struct A { A(int); }; A a = A(10);
|
||||
CK_ConstructorConversion,
|
||||
|
||||
/// CK_IntegralToPointer - Integral to pointer. A special kind of
|
||||
/// reinterpreting conversion. Applies to normal, ObjC, and block
|
||||
/// pointers.
|
||||
/// (char*) 0x1001aab0
|
||||
/// reinterpret_cast<int*>(0)
|
||||
CK_IntegralToPointer,
|
||||
|
||||
/// CK_PointerToIntegral - Pointer to integral. A special kind of
|
||||
/// reinterpreting conversion. Applies to normal, ObjC, and block
|
||||
/// pointers.
|
||||
/// (intptr_t) "help!"
|
||||
CK_PointerToIntegral,
|
||||
|
||||
/// CK_PointerToBoolean - Pointer to boolean conversion. A check
|
||||
/// against null. Applies to normal, ObjC, and block pointers.
|
||||
CK_PointerToBoolean,
|
||||
|
||||
/// CK_ToVoid - Cast to void, discarding the computed value.
|
||||
/// (void) malloc(2048)
|
||||
CK_ToVoid,
|
||||
|
||||
/// CK_VectorSplat - A conversion from an arithmetic type to a
|
||||
/// vector of that element type. Fills all elements ("splats") with
|
||||
/// the source value.
|
||||
/// __attribute__((ext_vector_type(4))) int v = 5;
|
||||
CK_VectorSplat,
|
||||
|
||||
/// CK_IntegralCast - A cast between integral types (other than to
|
||||
/// boolean). Variously a bitcast, a truncation, a sign-extension,
|
||||
/// or a zero-extension.
|
||||
/// long l = 5;
|
||||
/// (unsigned) i
|
||||
CK_IntegralCast,
|
||||
|
||||
/// CK_IntegralToBoolean - Integral to boolean. A check against zero.
|
||||
/// (bool) i
|
||||
CK_IntegralToBoolean,
|
||||
|
||||
/// CK_IntegralToFloating - Integral to floating point.
|
||||
/// float f = i;
|
||||
CK_IntegralToFloating,
|
||||
|
||||
/// CK_FloatingToIntegral - Floating point to integral. Rounds
|
||||
/// towards zero, discarding any fractional component.
|
||||
/// (int) f
|
||||
CK_FloatingToIntegral,
|
||||
|
||||
/// CK_FloatingToBoolean - Floating point to boolean.
|
||||
/// (bool) f
|
||||
CK_FloatingToBoolean,
|
||||
|
||||
/// CK_FloatingCast - Casting between floating types of different size.
|
||||
/// (double) f
|
||||
/// (float) ld
|
||||
CK_FloatingCast,
|
||||
|
||||
/// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an
|
||||
/// Objective-C pointer.
|
||||
CK_CPointerToObjCPointerCast,
|
||||
|
||||
/// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an
|
||||
/// ObjC pointer.
|
||||
CK_BlockPointerToObjCPointerCast,
|
||||
|
||||
/// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer
|
||||
/// to a block pointer. Block-to-block casts are bitcasts.
|
||||
CK_AnyPointerToBlockPointerCast,
|
||||
|
||||
/// \brief Converting between two Objective-C object types, which
|
||||
/// can occur when performing reference binding to an Objective-C
|
||||
/// object.
|
||||
CK_ObjCObjectLValueCast,
|
||||
|
||||
/// \brief A conversion of a floating point real to a floating point
|
||||
/// complex of the original type. Injects the value as the real
|
||||
/// component with a zero imaginary component.
|
||||
/// float -> _Complex float
|
||||
CK_FloatingRealToComplex,
|
||||
|
||||
/// \brief Converts a floating point complex to floating point real
|
||||
/// of the source's element type. Just discards the imaginary
|
||||
/// component.
|
||||
/// _Complex long double -> long double
|
||||
CK_FloatingComplexToReal,
|
||||
|
||||
/// \brief Converts a floating point complex to bool by comparing
|
||||
/// against 0+0i.
|
||||
CK_FloatingComplexToBoolean,
|
||||
|
||||
/// \brief Converts between different floating point complex types.
|
||||
/// _Complex float -> _Complex double
|
||||
CK_FloatingComplexCast,
|
||||
|
||||
/// \brief Converts from a floating complex to an integral complex.
|
||||
/// _Complex float -> _Complex int
|
||||
CK_FloatingComplexToIntegralComplex,
|
||||
|
||||
/// \brief Converts from an integral real to an integral complex
|
||||
/// whose element type matches the source. Injects the value as
|
||||
/// the real component with a zero imaginary component.
|
||||
/// long -> _Complex long
|
||||
CK_IntegralRealToComplex,
|
||||
|
||||
/// \brief Converts an integral complex to an integral real of the
|
||||
/// source's element type by discarding the imaginary component.
|
||||
/// _Complex short -> short
|
||||
CK_IntegralComplexToReal,
|
||||
|
||||
/// \brief Converts an integral complex to bool by comparing against
|
||||
/// 0+0i.
|
||||
CK_IntegralComplexToBoolean,
|
||||
|
||||
/// \brief Converts between different integral complex types.
|
||||
/// _Complex char -> _Complex long long
|
||||
/// _Complex unsigned int -> _Complex signed int
|
||||
CK_IntegralComplexCast,
|
||||
|
||||
/// \brief Converts from an integral complex to a floating complex.
|
||||
/// _Complex unsigned -> _Complex float
|
||||
CK_IntegralComplexToFloatingComplex,
|
||||
|
||||
/// \brief [ARC] Produces a retainable object pointer so that it may
|
||||
/// be consumed, e.g. by being passed to a consuming parameter.
|
||||
/// Calls objc_retain.
|
||||
CK_ARCProduceObject,
|
||||
|
||||
/// \brief [ARC] Consumes a retainable object pointer that has just
|
||||
/// been produced, e.g. as the return value of a retaining call.
|
||||
/// Enters a cleanup to call objc_release at some indefinite time.
|
||||
CK_ARCConsumeObject,
|
||||
|
||||
/// \brief [ARC] Reclaim a retainable object pointer object that may
|
||||
/// have been produced and autoreleased as part of a function return
|
||||
/// sequence.
|
||||
CK_ARCReclaimReturnedObject,
|
||||
|
||||
/// \brief [ARC] Causes a value of block type to be copied to the
|
||||
/// heap, if it is not already there. A number of other operations
|
||||
/// in ARC cause blocks to be copied; this is for cases where that
|
||||
/// would not otherwise be guaranteed, such as when casting to a
|
||||
/// non-block pointer type.
|
||||
CK_ARCExtendBlockObject,
|
||||
|
||||
/// \brief Converts from _Atomic(T) to T.
|
||||
CK_AtomicToNonAtomic,
|
||||
/// \brief Converts from T to _Atomic(T).
|
||||
CK_NonAtomicToAtomic,
|
||||
|
||||
/// \brief Causes a block literal to by copied to the heap and then
|
||||
/// autoreleased.
|
||||
///
|
||||
/// This particular cast kind is used for the conversion from a C++11
|
||||
/// lambda expression to a block pointer.
|
||||
CK_CopyAndAutoreleaseBlockObject,
|
||||
|
||||
// Convert a builtin function to a function pointer; only allowed in the
|
||||
// callee of a call expression.
|
||||
CK_BuiltinFnToFnPtr,
|
||||
|
||||
// Convert a zero value for OpenCL event_t initialization.
|
||||
CK_ZeroToOCLEvent
|
||||
};
|
||||
|
||||
static const CastKind CK_Invalid = static_cast<CastKind>(-1);
|
||||
|
||||
enum BinaryOperatorKind {
|
||||
// Operators listed in order of precedence.
|
||||
// Note that additions to this should also update the StmtVisitor class.
|
||||
BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators.
|
||||
BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators.
|
||||
BO_Add, BO_Sub, // [C99 6.5.6] Additive operators.
|
||||
BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators.
|
||||
BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators.
|
||||
BO_EQ, BO_NE, // [C99 6.5.9] Equality operators.
|
||||
BO_And, // [C99 6.5.10] Bitwise AND operator.
|
||||
BO_Xor, // [C99 6.5.11] Bitwise XOR operator.
|
||||
BO_Or, // [C99 6.5.12] Bitwise OR operator.
|
||||
BO_LAnd, // [C99 6.5.13] Logical AND operator.
|
||||
BO_LOr, // [C99 6.5.14] Logical OR operator.
|
||||
BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators.
|
||||
BO_DivAssign, BO_RemAssign,
|
||||
BO_AddAssign, BO_SubAssign,
|
||||
BO_ShlAssign, BO_ShrAssign,
|
||||
BO_AndAssign, BO_XorAssign,
|
||||
BO_OrAssign,
|
||||
BO_Comma // [C99 6.5.17] Comma operator.
|
||||
};
|
||||
|
||||
enum UnaryOperatorKind {
|
||||
// Note that additions to this should also update the StmtVisitor class.
|
||||
UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement
|
||||
UO_PreInc, UO_PreDec, // [C99 6.5.3.1] Prefix increment and decrement
|
||||
UO_AddrOf, UO_Deref, // [C99 6.5.3.2] Address and indirection
|
||||
UO_Plus, UO_Minus, // [C99 6.5.3.3] Unary arithmetic
|
||||
UO_Not, UO_LNot, // [C99 6.5.3.3] Unary arithmetic
|
||||
UO_Real, UO_Imag, // "__real expr"/"__imag expr" Extension.
|
||||
UO_Extension // __extension__ marker.
|
||||
};
|
||||
|
||||
/// \brief The kind of bridging performed by the Objective-C bridge cast.
|
||||
enum ObjCBridgeCastKind {
|
||||
/// \brief Bridging via __bridge, which does nothing but reinterpret
|
||||
/// the bits.
|
||||
OBC_Bridge,
|
||||
/// \brief Bridging via __bridge_transfer, which transfers ownership of an
|
||||
/// Objective-C pointer into ARC.
|
||||
OBC_BridgeTransfer,
|
||||
/// \brief Bridging via __bridge_retain, which makes an ARC object available
|
||||
/// as a +1 C pointer.
|
||||
OBC_BridgeRetained
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
62
thirdparty/clang/include/clang/AST/ParentMap.h
vendored
Normal file
62
thirdparty/clang/include/clang/AST/ParentMap.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ParentMap class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_PARENTMAP_H
|
||||
#define LLVM_CLANG_PARENTMAP_H
|
||||
|
||||
namespace clang {
|
||||
class Stmt;
|
||||
class Expr;
|
||||
|
||||
class ParentMap {
|
||||
void* Impl;
|
||||
public:
|
||||
ParentMap(Stmt* ASTRoot);
|
||||
~ParentMap();
|
||||
|
||||
/// \brief Adds and/or updates the parent/child-relations of the complete
|
||||
/// stmt tree of S. All children of S including indirect descendants are
|
||||
/// visited and updated or inserted but not the parents of S.
|
||||
void addStmt(Stmt* S);
|
||||
|
||||
Stmt *getParent(Stmt*) const;
|
||||
Stmt *getParentIgnoreParens(Stmt *) const;
|
||||
Stmt *getParentIgnoreParenCasts(Stmt *) const;
|
||||
Stmt *getParentIgnoreParenImpCasts(Stmt *) const;
|
||||
Stmt *getOuterParenParent(Stmt *) const;
|
||||
|
||||
const Stmt *getParent(const Stmt* S) const {
|
||||
return getParent(const_cast<Stmt*>(S));
|
||||
}
|
||||
|
||||
const Stmt *getParentIgnoreParens(const Stmt *S) const {
|
||||
return getParentIgnoreParens(const_cast<Stmt*>(S));
|
||||
}
|
||||
|
||||
const Stmt *getParentIgnoreParenCasts(const Stmt *S) const {
|
||||
return getParentIgnoreParenCasts(const_cast<Stmt*>(S));
|
||||
}
|
||||
|
||||
bool hasParent(Stmt* S) const {
|
||||
return getParent(S) != 0;
|
||||
}
|
||||
|
||||
bool isConsumedExpr(Expr *E) const;
|
||||
|
||||
bool isConsumedExpr(const Expr *E) const {
|
||||
return isConsumedExpr(const_cast<Expr*>(E));
|
||||
}
|
||||
};
|
||||
|
||||
} // end clang namespace
|
||||
#endif
|
||||
153
thirdparty/clang/include/clang/AST/PrettyPrinter.h
vendored
Normal file
153
thirdparty/clang/include/clang/AST/PrettyPrinter.h
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
//===--- PrettyPrinter.h - Classes for aiding with AST printing -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the PrinterHelper interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H
|
||||
#define LLVM_CLANG_AST_PRETTY_PRINTER_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class LangOptions;
|
||||
class SourceManager;
|
||||
class Stmt;
|
||||
class TagDecl;
|
||||
|
||||
class PrinterHelper {
|
||||
public:
|
||||
virtual ~PrinterHelper();
|
||||
virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
|
||||
};
|
||||
|
||||
/// \brief Describes how types, statements, expressions, and
|
||||
/// declarations should be printed.
|
||||
struct PrintingPolicy {
|
||||
/// \brief Create a default printing policy for C.
|
||||
PrintingPolicy(const LangOptions &LO)
|
||||
: LangOpts(LO), Indentation(2), SuppressSpecifiers(false),
|
||||
SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
|
||||
SuppressUnwrittenScope(false), SuppressInitializers(false),
|
||||
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
|
||||
SuppressStrongLifetime(false), Bool(LO.Bool),
|
||||
TerseOutput(false), PolishForDeclaration(false) { }
|
||||
|
||||
/// \brief What language we're printing.
|
||||
LangOptions LangOpts;
|
||||
|
||||
/// \brief The number of spaces to use to indent each line.
|
||||
unsigned Indentation : 8;
|
||||
|
||||
/// \brief Whether we should suppress printing of the actual specifiers for
|
||||
/// the given type or declaration.
|
||||
///
|
||||
/// This flag is only used when we are printing declarators beyond
|
||||
/// the first declarator within a declaration group. For example, given:
|
||||
///
|
||||
/// \code
|
||||
/// const int *x, *y;
|
||||
/// \endcode
|
||||
///
|
||||
/// SuppressSpecifiers will be false when printing the
|
||||
/// declaration for "x", so that we will print "int *x"; it will be
|
||||
/// \c true when we print "y", so that we suppress printing the
|
||||
/// "const int" type specifier and instead only print the "*y".
|
||||
bool SuppressSpecifiers : 1;
|
||||
|
||||
/// \brief Whether type printing should skip printing the tag keyword.
|
||||
///
|
||||
/// This is used when printing the inner type of elaborated types,
|
||||
/// (as the tag keyword is part of the elaborated type):
|
||||
///
|
||||
/// \code
|
||||
/// struct Geometry::Point;
|
||||
/// \endcode
|
||||
bool SuppressTagKeyword : 1;
|
||||
|
||||
/// \brief Whether type printing should skip printing the actual tag type.
|
||||
///
|
||||
/// This is used when the caller needs to print a tag definition in front
|
||||
/// of the type, as in constructs like the following:
|
||||
///
|
||||
/// \code
|
||||
/// typedef struct { int x, y; } Point;
|
||||
/// \endcode
|
||||
bool SuppressTag : 1;
|
||||
|
||||
/// \brief Suppresses printing of scope specifiers.
|
||||
bool SuppressScope : 1;
|
||||
|
||||
/// \brief Suppress printing parts of scope specifiers that don't need
|
||||
/// to be written, e.g., for inline or anonymous namespaces.
|
||||
bool SuppressUnwrittenScope : 1;
|
||||
|
||||
/// \brief Suppress printing of variable initializers.
|
||||
///
|
||||
/// This flag is used when printing the loop variable in a for-range
|
||||
/// statement. For example, given:
|
||||
///
|
||||
/// \code
|
||||
/// for (auto x : coll)
|
||||
/// \endcode
|
||||
///
|
||||
/// SuppressInitializers will be true when printing "auto x", so that the
|
||||
/// internal initializer constructed for x will not be printed.
|
||||
bool SuppressInitializers : 1;
|
||||
|
||||
/// \brief Whether we should print the sizes of constant array expressions
|
||||
/// as written in the sources.
|
||||
///
|
||||
/// This flag is determines whether arrays types declared as
|
||||
///
|
||||
/// \code
|
||||
/// int a[4+10*10];
|
||||
/// char a[] = "A string";
|
||||
/// \endcode
|
||||
///
|
||||
/// will be printed as written or as follows:
|
||||
///
|
||||
/// \code
|
||||
/// int a[104];
|
||||
/// char a[9] = "A string";
|
||||
/// \endcode
|
||||
bool ConstantArraySizeAsWritten : 1;
|
||||
|
||||
/// \brief When printing an anonymous tag name, also print the location of
|
||||
/// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
|
||||
/// prints "<anonymous>" for the name.
|
||||
bool AnonymousTagLocations : 1;
|
||||
|
||||
/// \brief When true, suppress printing of the __strong lifetime qualifier in
|
||||
/// ARC.
|
||||
unsigned SuppressStrongLifetime : 1;
|
||||
|
||||
/// \brief Whether we can use 'bool' rather than '_Bool', even if the language
|
||||
/// doesn't actually have 'bool' (because, e.g., it is defined as a macro).
|
||||
unsigned Bool : 1;
|
||||
|
||||
/// \brief Provide a 'terse' output.
|
||||
///
|
||||
/// For example, in this mode we don't print function bodies, class members,
|
||||
/// declarations inside namespaces etc. Effectively, this should print
|
||||
/// only the requested declaration.
|
||||
unsigned TerseOutput : 1;
|
||||
|
||||
/// \brief When true, do certain refinement needed for producing proper
|
||||
/// declaration tag; such as, do not print attributes attached to the declaration.
|
||||
///
|
||||
unsigned PolishForDeclaration : 1;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
222
thirdparty/clang/include/clang/AST/RawCommentList.h
vendored
Normal file
222
thirdparty/clang/include/clang/AST/RawCommentList.h
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H
|
||||
#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H
|
||||
|
||||
#include "clang/Basic/CommentOptions.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class ASTReader;
|
||||
class Decl;
|
||||
class Preprocessor;
|
||||
|
||||
namespace comments {
|
||||
class FullComment;
|
||||
} // end namespace comments
|
||||
|
||||
class RawComment {
|
||||
public:
|
||||
enum CommentKind {
|
||||
RCK_Invalid, ///< Invalid comment
|
||||
RCK_OrdinaryBCPL, ///< Any normal BCPL comments
|
||||
RCK_OrdinaryC, ///< Any normal C comment
|
||||
RCK_BCPLSlash, ///< \code /// stuff \endcode
|
||||
RCK_BCPLExcl, ///< \code //! stuff \endcode
|
||||
RCK_JavaDoc, ///< \code /** stuff */ \endcode
|
||||
RCK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc
|
||||
RCK_Merged ///< Two or more documentation comments merged together
|
||||
};
|
||||
|
||||
RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { }
|
||||
|
||||
RawComment(const SourceManager &SourceMgr, SourceRange SR,
|
||||
bool Merged, bool ParseAllComments);
|
||||
|
||||
CommentKind getKind() const LLVM_READONLY {
|
||||
return (CommentKind) Kind;
|
||||
}
|
||||
|
||||
bool isInvalid() const LLVM_READONLY {
|
||||
return Kind == RCK_Invalid;
|
||||
}
|
||||
|
||||
bool isMerged() const LLVM_READONLY {
|
||||
return Kind == RCK_Merged;
|
||||
}
|
||||
|
||||
/// Is this comment attached to any declaration?
|
||||
bool isAttached() const LLVM_READONLY {
|
||||
return IsAttached;
|
||||
}
|
||||
|
||||
void setAttached() {
|
||||
IsAttached = true;
|
||||
}
|
||||
|
||||
/// Returns true if it is a comment that should be put after a member:
|
||||
/// \code ///< stuff \endcode
|
||||
/// \code //!< stuff \endcode
|
||||
/// \code /**< stuff */ \endcode
|
||||
/// \code /*!< stuff */ \endcode
|
||||
bool isTrailingComment() const LLVM_READONLY {
|
||||
assert(isDocumentation());
|
||||
return IsTrailingComment;
|
||||
}
|
||||
|
||||
/// Returns true if it is a probable typo:
|
||||
/// \code //< stuff \endcode
|
||||
/// \code /*< stuff */ \endcode
|
||||
bool isAlmostTrailingComment() const LLVM_READONLY {
|
||||
return IsAlmostTrailingComment;
|
||||
}
|
||||
|
||||
/// Returns true if this comment is not a documentation comment.
|
||||
bool isOrdinary() const LLVM_READONLY {
|
||||
return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) &&
|
||||
!ParseAllComments;
|
||||
}
|
||||
|
||||
/// Returns true if this comment any kind of a documentation comment.
|
||||
bool isDocumentation() const LLVM_READONLY {
|
||||
return !isInvalid() && !isOrdinary();
|
||||
}
|
||||
|
||||
/// Returns whether we are parsing all comments.
|
||||
bool isParseAllComments() const LLVM_READONLY {
|
||||
return ParseAllComments;
|
||||
}
|
||||
|
||||
/// Returns raw comment text with comment markers.
|
||||
StringRef getRawText(const SourceManager &SourceMgr) const {
|
||||
if (RawTextValid)
|
||||
return RawText;
|
||||
|
||||
RawText = getRawTextSlow(SourceMgr);
|
||||
RawTextValid = true;
|
||||
return RawText;
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return Range;
|
||||
}
|
||||
|
||||
unsigned getBeginLine(const SourceManager &SM) const;
|
||||
unsigned getEndLine(const SourceManager &SM) const;
|
||||
|
||||
const char *getBriefText(const ASTContext &Context) const {
|
||||
if (BriefTextValid)
|
||||
return BriefText;
|
||||
|
||||
return extractBriefText(Context);
|
||||
}
|
||||
|
||||
/// Parse the comment, assuming it is attached to decl \c D.
|
||||
comments::FullComment *parse(const ASTContext &Context,
|
||||
const Preprocessor *PP, const Decl *D) const;
|
||||
|
||||
private:
|
||||
SourceRange Range;
|
||||
|
||||
mutable StringRef RawText;
|
||||
mutable const char *BriefText;
|
||||
|
||||
mutable bool RawTextValid : 1; ///< True if RawText is valid
|
||||
mutable bool BriefTextValid : 1; ///< True if BriefText is valid
|
||||
|
||||
unsigned Kind : 3;
|
||||
|
||||
/// True if comment is attached to a declaration in ASTContext.
|
||||
bool IsAttached : 1;
|
||||
|
||||
bool IsTrailingComment : 1;
|
||||
bool IsAlmostTrailingComment : 1;
|
||||
|
||||
/// When true, ordinary comments starting with "//" and "/*" will be
|
||||
/// considered as documentation comments.
|
||||
bool ParseAllComments : 1;
|
||||
|
||||
mutable bool BeginLineValid : 1; ///< True if BeginLine is valid
|
||||
mutable bool EndLineValid : 1; ///< True if EndLine is valid
|
||||
mutable unsigned BeginLine; ///< Cached line number
|
||||
mutable unsigned EndLine; ///< Cached line number
|
||||
|
||||
/// \brief Constructor for AST deserialization.
|
||||
RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
|
||||
bool IsAlmostTrailingComment,
|
||||
bool ParseAllComments) :
|
||||
Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
|
||||
IsAttached(false), IsTrailingComment(IsTrailingComment),
|
||||
IsAlmostTrailingComment(IsAlmostTrailingComment),
|
||||
ParseAllComments(ParseAllComments),
|
||||
BeginLineValid(false), EndLineValid(false)
|
||||
{ }
|
||||
|
||||
StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
|
||||
|
||||
const char *extractBriefText(const ASTContext &Context) const;
|
||||
|
||||
friend class ASTReader;
|
||||
};
|
||||
|
||||
/// \brief Compare comments' source locations.
|
||||
template<>
|
||||
class BeforeThanCompare<RawComment> {
|
||||
const SourceManager &SM;
|
||||
|
||||
public:
|
||||
explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
|
||||
|
||||
bool operator()(const RawComment &LHS, const RawComment &RHS) {
|
||||
return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(),
|
||||
RHS.getSourceRange().getBegin());
|
||||
}
|
||||
|
||||
bool operator()(const RawComment *LHS, const RawComment *RHS) {
|
||||
return operator()(*LHS, *RHS);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief This class represents all comments included in the translation unit,
|
||||
/// sorted in order of appearance in the translation unit.
|
||||
class RawCommentList {
|
||||
public:
|
||||
RawCommentList(SourceManager &SourceMgr) :
|
||||
SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { }
|
||||
|
||||
void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator);
|
||||
|
||||
ArrayRef<RawComment *> getComments() const {
|
||||
return Comments;
|
||||
}
|
||||
|
||||
private:
|
||||
SourceManager &SourceMgr;
|
||||
std::vector<RawComment *> Comments;
|
||||
SourceLocation PrevCommentEndLoc;
|
||||
bool OnlyWhitespaceSeen;
|
||||
|
||||
void addCommentsToFront(const std::vector<RawComment *> &C) {
|
||||
size_t OldSize = Comments.size();
|
||||
Comments.resize(C.size() + OldSize);
|
||||
std::copy_backward(Comments.begin(), Comments.begin() + OldSize,
|
||||
Comments.end());
|
||||
std::copy(C.begin(), C.end(), Comments.begin());
|
||||
}
|
||||
|
||||
friend class ASTReader;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
244
thirdparty/clang/include/clang/AST/RecordLayout.h
vendored
Normal file
244
thirdparty/clang/include/clang/AST/RecordLayout.h
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
//===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the RecordLayout interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
|
||||
#define LLVM_CLANG_AST_LAYOUTINFO_H
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class FieldDecl;
|
||||
class RecordDecl;
|
||||
class CXXRecordDecl;
|
||||
|
||||
/// ASTRecordLayout -
|
||||
/// This class contains layout information for one RecordDecl,
|
||||
/// which is a struct/union/class. The decl represented must be a definition,
|
||||
/// not a forward declaration.
|
||||
/// This class is also used to contain layout information for one
|
||||
/// ObjCInterfaceDecl. FIXME - Find appropriate name.
|
||||
/// These objects are managed by ASTContext.
|
||||
class ASTRecordLayout {
|
||||
public:
|
||||
struct VBaseInfo {
|
||||
/// The offset to this virtual base in the complete-object layout
|
||||
/// of this class.
|
||||
CharUnits VBaseOffset;
|
||||
|
||||
private:
|
||||
/// Whether this virtual base requires a vtordisp field in the
|
||||
/// Microsoft ABI. These fields are required for certain operations
|
||||
/// in constructors and destructors.
|
||||
bool HasVtorDisp;
|
||||
|
||||
public:
|
||||
bool hasVtorDisp() const { return HasVtorDisp; }
|
||||
|
||||
VBaseInfo() : HasVtorDisp(false) {}
|
||||
|
||||
VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
|
||||
VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
|
||||
};
|
||||
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
|
||||
VBaseOffsetsMapTy;
|
||||
|
||||
private:
|
||||
/// Size - Size of record in characters.
|
||||
CharUnits Size;
|
||||
|
||||
/// DataSize - Size of record in characters without tail padding.
|
||||
CharUnits DataSize;
|
||||
|
||||
// Alignment - Alignment of record in characters.
|
||||
CharUnits Alignment;
|
||||
|
||||
/// FieldOffsets - Array of field offsets in bits.
|
||||
uint64_t *FieldOffsets;
|
||||
|
||||
// FieldCount - Number of fields.
|
||||
unsigned FieldCount;
|
||||
|
||||
/// CXXRecordLayoutInfo - Contains C++ specific layout information.
|
||||
struct CXXRecordLayoutInfo {
|
||||
/// NonVirtualSize - The non-virtual size (in chars) of an object, which is
|
||||
/// the size of the object without virtual bases.
|
||||
CharUnits NonVirtualSize;
|
||||
|
||||
/// NonVirtualAlign - The non-virtual alignment (in chars) of an object,
|
||||
/// which is the alignment of the object without virtual bases.
|
||||
CharUnits NonVirtualAlign;
|
||||
|
||||
/// SizeOfLargestEmptySubobject - The size of the largest empty subobject
|
||||
/// (either a base or a member). Will be zero if the class doesn't contain
|
||||
/// any empty subobjects.
|
||||
CharUnits SizeOfLargestEmptySubobject;
|
||||
|
||||
/// VBPtrOffset - Virtual base table offset (Microsoft-only).
|
||||
CharUnits VBPtrOffset;
|
||||
|
||||
/// HasOwnVFPtr - Does this class provide a virtual function table
|
||||
/// (vtable in Itanium, vftbl in Microsoft) that is independent from
|
||||
/// its base classes?
|
||||
bool HasOwnVFPtr; // TODO: stash this somewhere more efficient
|
||||
|
||||
/// PrimaryBase - The primary base info for this record.
|
||||
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
|
||||
|
||||
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
|
||||
|
||||
/// BaseOffsets - Contains a map from base classes to their offset.
|
||||
BaseOffsetsMapTy BaseOffsets;
|
||||
|
||||
/// VBaseOffsets - Contains a map from vbase classes to their offset.
|
||||
VBaseOffsetsMapTy VBaseOffsets;
|
||||
};
|
||||
|
||||
/// CXXInfo - If the record layout is for a C++ record, this will have
|
||||
/// C++ specific information about the record.
|
||||
CXXRecordLayoutInfo *CXXInfo;
|
||||
|
||||
friend class ASTContext;
|
||||
|
||||
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
|
||||
CharUnits datasize, const uint64_t *fieldoffsets,
|
||||
unsigned fieldcount);
|
||||
|
||||
// Constructor for C++ records.
|
||||
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
|
||||
ASTRecordLayout(const ASTContext &Ctx,
|
||||
CharUnits size, CharUnits alignment,
|
||||
bool hasOwnVFPtr, CharUnits vbptroffset,
|
||||
CharUnits datasize,
|
||||
const uint64_t *fieldoffsets, unsigned fieldcount,
|
||||
CharUnits nonvirtualsize, CharUnits nonvirtualalign,
|
||||
CharUnits SizeOfLargestEmptySubobject,
|
||||
const CXXRecordDecl *PrimaryBase,
|
||||
bool IsPrimaryBaseVirtual,
|
||||
const BaseOffsetsMapTy& BaseOffsets,
|
||||
const VBaseOffsetsMapTy& VBaseOffsets);
|
||||
|
||||
~ASTRecordLayout() {}
|
||||
|
||||
void Destroy(ASTContext &Ctx);
|
||||
|
||||
ASTRecordLayout(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
|
||||
/// getAlignment - Get the record alignment in characters.
|
||||
CharUnits getAlignment() const { return Alignment; }
|
||||
|
||||
/// getSize - Get the record size in characters.
|
||||
CharUnits getSize() const { return Size; }
|
||||
|
||||
/// getFieldCount - Get the number of fields in the layout.
|
||||
unsigned getFieldCount() const { return FieldCount; }
|
||||
|
||||
/// getFieldOffset - Get the offset of the given field index, in
|
||||
/// bits.
|
||||
uint64_t getFieldOffset(unsigned FieldNo) const {
|
||||
assert (FieldNo < FieldCount && "Invalid Field No");
|
||||
return FieldOffsets[FieldNo];
|
||||
}
|
||||
|
||||
/// getDataSize() - Get the record data size, which is the record size
|
||||
/// without tail padding, in characters.
|
||||
CharUnits getDataSize() const {
|
||||
return DataSize;
|
||||
}
|
||||
|
||||
/// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
|
||||
/// which is the size of the object without virtual bases.
|
||||
CharUnits getNonVirtualSize() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
|
||||
return CXXInfo->NonVirtualSize;
|
||||
}
|
||||
|
||||
/// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
|
||||
/// which is the alignment of the object without virtual bases.
|
||||
CharUnits getNonVirtualAlign() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
|
||||
return CXXInfo->NonVirtualAlign;
|
||||
}
|
||||
|
||||
/// getPrimaryBase - Get the primary base for this record.
|
||||
const CXXRecordDecl *getPrimaryBase() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
|
||||
return CXXInfo->PrimaryBase.getPointer();
|
||||
}
|
||||
|
||||
/// isPrimaryBaseVirtual - Get whether the primary base for this record
|
||||
/// is virtual or not.
|
||||
bool isPrimaryBaseVirtual() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
|
||||
return CXXInfo->PrimaryBase.getInt();
|
||||
}
|
||||
|
||||
/// getBaseClassOffset - Get the offset, in chars, for the given base class.
|
||||
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
|
||||
|
||||
return CXXInfo->BaseOffsets[Base];
|
||||
}
|
||||
|
||||
/// getVBaseClassOffset - Get the offset, in chars, for the given base class.
|
||||
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
|
||||
|
||||
return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
|
||||
}
|
||||
|
||||
CharUnits getSizeOfLargestEmptySubobject() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
return CXXInfo->SizeOfLargestEmptySubobject;
|
||||
}
|
||||
|
||||
/// hasOwnVFPtr - Does this class provide its own virtual-function
|
||||
/// table pointer, rather than inheriting one from a primary base
|
||||
/// class? If so, it is at offset zero.
|
||||
///
|
||||
/// This implies that the ABI has no primary base class, meaning
|
||||
/// that it has no base classes that are suitable under the conditions
|
||||
/// of the ABI.
|
||||
bool hasOwnVFPtr() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
return CXXInfo->HasOwnVFPtr;
|
||||
}
|
||||
|
||||
/// getVBPtrOffset - Get the offset for virtual base table pointer.
|
||||
/// This is only meaningful with the Microsoft ABI.
|
||||
CharUnits getVBPtrOffset() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
return CXXInfo->VBPtrOffset;
|
||||
}
|
||||
|
||||
const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
return CXXInfo->VBaseOffsets;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
2292
thirdparty/clang/include/clang/AST/RecursiveASTVisitor.h
vendored
Normal file
2292
thirdparty/clang/include/clang/AST/RecursiveASTVisitor.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
180
thirdparty/clang/include/clang/AST/Redeclarable.h
vendored
Normal file
180
thirdparty/clang/include/clang/AST/Redeclarable.h
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
//===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Redeclarable interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_REDECLARABLE_H
|
||||
#define LLVM_CLANG_AST_REDECLARABLE_H
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief Provides common interface for the Decls that can be redeclared.
|
||||
template<typename decl_type>
|
||||
class Redeclarable {
|
||||
|
||||
protected:
|
||||
class DeclLink {
|
||||
llvm::PointerIntPair<decl_type *, 1, bool> NextAndIsPrevious;
|
||||
public:
|
||||
DeclLink(decl_type *D, bool isLatest)
|
||||
: NextAndIsPrevious(D, isLatest) { }
|
||||
|
||||
bool NextIsPrevious() const { return !NextAndIsPrevious.getInt(); }
|
||||
bool NextIsLatest() const { return NextAndIsPrevious.getInt(); }
|
||||
decl_type *getNext() const { return NextAndIsPrevious.getPointer(); }
|
||||
void setNext(decl_type *D) { NextAndIsPrevious.setPointer(D); }
|
||||
};
|
||||
|
||||
static DeclLink PreviousDeclLink(decl_type *D) {
|
||||
return DeclLink(D, false);
|
||||
}
|
||||
|
||||
static DeclLink LatestDeclLink(decl_type *D) {
|
||||
return DeclLink(D, true);
|
||||
}
|
||||
|
||||
/// \brief Points to the next redeclaration in the chain.
|
||||
///
|
||||
/// If NextIsPrevious() is true, this is a link to the previous declaration
|
||||
/// of this same Decl. If NextIsLatest() is true, this is the first
|
||||
/// declaration and Link points to the latest declaration. For example:
|
||||
///
|
||||
/// #1 int f(int x, int y = 1); // <pointer to #3, true>
|
||||
/// #2 int f(int x = 0, int y); // <pointer to #1, false>
|
||||
/// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
|
||||
///
|
||||
/// If there is only one declaration, it is <pointer to self, true>
|
||||
DeclLink RedeclLink;
|
||||
|
||||
public:
|
||||
Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { }
|
||||
|
||||
/// \brief Return the previous declaration of this declaration or NULL if this
|
||||
/// is the first declaration.
|
||||
decl_type *getPreviousDecl() {
|
||||
if (RedeclLink.NextIsPrevious())
|
||||
return RedeclLink.getNext();
|
||||
return 0;
|
||||
}
|
||||
const decl_type *getPreviousDecl() const {
|
||||
return const_cast<decl_type *>(
|
||||
static_cast<const decl_type*>(this))->getPreviousDecl();
|
||||
}
|
||||
|
||||
/// \brief Return the first declaration of this declaration or itself if this
|
||||
/// is the only declaration.
|
||||
decl_type *getFirstDeclaration() {
|
||||
decl_type *D = static_cast<decl_type*>(this);
|
||||
while (D->getPreviousDecl())
|
||||
D = D->getPreviousDecl();
|
||||
return D;
|
||||
}
|
||||
|
||||
/// \brief Return the first declaration of this declaration or itself if this
|
||||
/// is the only declaration.
|
||||
const decl_type *getFirstDeclaration() const {
|
||||
const decl_type *D = static_cast<const decl_type*>(this);
|
||||
while (D->getPreviousDecl())
|
||||
D = D->getPreviousDecl();
|
||||
return D;
|
||||
}
|
||||
|
||||
/// \brief Returns true if this is the first declaration.
|
||||
bool isFirstDeclaration() const {
|
||||
return RedeclLink.NextIsLatest();
|
||||
}
|
||||
|
||||
/// \brief Returns the most recent (re)declaration of this declaration.
|
||||
decl_type *getMostRecentDecl() {
|
||||
return getFirstDeclaration()->RedeclLink.getNext();
|
||||
}
|
||||
|
||||
/// \brief Returns the most recent (re)declaration of this declaration.
|
||||
const decl_type *getMostRecentDecl() const {
|
||||
return getFirstDeclaration()->RedeclLink.getNext();
|
||||
}
|
||||
|
||||
/// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
|
||||
/// first and only declaration.
|
||||
void setPreviousDeclaration(decl_type *PrevDecl);
|
||||
|
||||
/// \brief Iterates through all the redeclarations of the same decl.
|
||||
class redecl_iterator {
|
||||
/// Current - The current declaration.
|
||||
decl_type *Current;
|
||||
decl_type *Starter;
|
||||
bool PassedFirst;
|
||||
|
||||
public:
|
||||
typedef decl_type* value_type;
|
||||
typedef decl_type* reference;
|
||||
typedef decl_type* pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
redecl_iterator() : Current(0) { }
|
||||
explicit redecl_iterator(decl_type *C)
|
||||
: Current(C), Starter(C), PassedFirst(false) { }
|
||||
|
||||
reference operator*() const { return Current; }
|
||||
pointer operator->() const { return Current; }
|
||||
|
||||
redecl_iterator& operator++() {
|
||||
assert(Current && "Advancing while iterator has reached end");
|
||||
// Sanity check to avoid infinite loop on invalid redecl chain.
|
||||
if (Current->isFirstDeclaration()) {
|
||||
if (PassedFirst) {
|
||||
assert(0 && "Passed first decl twice, invalid redecl chain!");
|
||||
Current = 0;
|
||||
return *this;
|
||||
}
|
||||
PassedFirst = true;
|
||||
}
|
||||
|
||||
// Get either previous decl or latest decl.
|
||||
decl_type *Next = Current->RedeclLink.getNext();
|
||||
Current = (Next != Starter ? Next : 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
redecl_iterator operator++(int) {
|
||||
redecl_iterator tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool operator==(redecl_iterator x, redecl_iterator y) {
|
||||
return x.Current == y.Current;
|
||||
}
|
||||
friend bool operator!=(redecl_iterator x, redecl_iterator y) {
|
||||
return x.Current != y.Current;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Returns iterator for all the redeclarations of the same decl.
|
||||
/// It will iterate at least once (when this decl is the only one).
|
||||
redecl_iterator redecls_begin() const {
|
||||
return redecl_iterator(const_cast<decl_type*>(
|
||||
static_cast<const decl_type*>(this)));
|
||||
}
|
||||
redecl_iterator redecls_end() const { return redecl_iterator(); }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
83
thirdparty/clang/include/clang/AST/SelectorLocationsKind.h
vendored
Normal file
83
thirdparty/clang/include/clang/AST/SelectorLocationsKind.h
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
//===--- SelectorLocationsKind.h - Kind of selector locations ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Describes whether the identifier locations for a selector are "standard"
|
||||
// or not.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
|
||||
#define LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
|
||||
namespace clang {
|
||||
class Selector;
|
||||
class SourceLocation;
|
||||
class Expr;
|
||||
class ParmVarDecl;
|
||||
|
||||
/// \brief Whether all locations of the selector identifiers are in a
|
||||
/// "standard" position.
|
||||
enum SelectorLocationsKind {
|
||||
/// \brief Non-standard.
|
||||
SelLoc_NonStandard = 0,
|
||||
|
||||
/// \brief For nullary selectors, immediately before the end:
|
||||
/// "[foo release]" / "-(void)release;"
|
||||
/// Or immediately before the arguments:
|
||||
/// "[foo first:1 second:2]" / "-(id)first:(int)x second:(int)y;
|
||||
SelLoc_StandardNoSpace = 1,
|
||||
|
||||
/// \brief For nullary selectors, immediately before the end:
|
||||
/// "[foo release]" / "-(void)release;"
|
||||
/// Or with a space between the arguments:
|
||||
/// "[foo first: 1 second: 2]" / "-(id)first: (int)x second: (int)y;
|
||||
SelLoc_StandardWithSpace = 2
|
||||
};
|
||||
|
||||
/// \brief Returns true if all \p SelLocs are in a "standard" location.
|
||||
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
/// \brief Get the "standard" location of a selector identifier, e.g:
|
||||
/// For nullary selectors, immediately before ']': "[foo release]"
|
||||
///
|
||||
/// \param WithArgSpace if true the standard location is with a space apart
|
||||
/// before arguments: "[foo first: 1 second: 2]"
|
||||
/// If false: "[foo first:1 second:2]"
|
||||
SourceLocation getStandardSelectorLoc(unsigned Index,
|
||||
Selector Sel,
|
||||
bool WithArgSpace,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
/// \brief Returns true if all \p SelLocs are in a "standard" location.
|
||||
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
ArrayRef<ParmVarDecl *> Args,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
/// \brief Get the "standard" location of a selector identifier, e.g:
|
||||
/// For nullary selectors, immediately before ']': "[foo release]"
|
||||
///
|
||||
/// \param WithArgSpace if true the standard location is with a space apart
|
||||
/// before arguments: "-(id)first: (int)x second: (int)y;"
|
||||
/// If false: "-(id)first:(int)x second:(int)y;"
|
||||
SourceLocation getStandardSelectorLoc(unsigned Index,
|
||||
Selector Sel,
|
||||
bool WithArgSpace,
|
||||
ArrayRef<ParmVarDecl *> Args,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
2053
thirdparty/clang/include/clang/AST/Stmt.h
vendored
Normal file
2053
thirdparty/clang/include/clang/AST/Stmt.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
292
thirdparty/clang/include/clang/AST/StmtCXX.h
vendored
Normal file
292
thirdparty/clang/include/clang/AST/StmtCXX.h
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
//===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the C++ statement AST node classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_STMTCXX_H
|
||||
#define LLVM_CLANG_AST_STMTCXX_H
|
||||
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class VarDecl;
|
||||
|
||||
/// CXXCatchStmt - This represents a C++ catch block.
|
||||
///
|
||||
class CXXCatchStmt : public Stmt {
|
||||
SourceLocation CatchLoc;
|
||||
/// The exception-declaration of the type.
|
||||
VarDecl *ExceptionDecl;
|
||||
/// The handler block.
|
||||
Stmt *HandlerBlock;
|
||||
|
||||
public:
|
||||
CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
|
||||
: Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
|
||||
HandlerBlock(handlerBlock) {}
|
||||
|
||||
CXXCatchStmt(EmptyShell Empty)
|
||||
: Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return HandlerBlock->getLocEnd();
|
||||
}
|
||||
|
||||
SourceLocation getCatchLoc() const { return CatchLoc; }
|
||||
VarDecl *getExceptionDecl() const { return ExceptionDecl; }
|
||||
QualType getCaughtType() const;
|
||||
Stmt *getHandlerBlock() const { return HandlerBlock; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXCatchStmtClass;
|
||||
}
|
||||
|
||||
child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
|
||||
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// CXXTryStmt - A C++ try block, including all handlers.
|
||||
///
|
||||
class CXXTryStmt : public Stmt {
|
||||
SourceLocation TryLoc;
|
||||
unsigned NumHandlers;
|
||||
|
||||
CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
|
||||
|
||||
CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
|
||||
: Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
|
||||
|
||||
Stmt const * const *getStmts() const {
|
||||
return reinterpret_cast<Stmt const * const*>(this + 1);
|
||||
}
|
||||
Stmt **getStmts() {
|
||||
return reinterpret_cast<Stmt **>(this + 1);
|
||||
}
|
||||
|
||||
public:
|
||||
static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
|
||||
Stmt *tryBlock, ArrayRef<Stmt*> handlers);
|
||||
|
||||
static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty,
|
||||
unsigned numHandlers);
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
|
||||
SourceLocation getTryLoc() const { return TryLoc; }
|
||||
SourceLocation getEndLoc() const {
|
||||
return getStmts()[NumHandlers]->getLocEnd();
|
||||
}
|
||||
|
||||
CompoundStmt *getTryBlock() {
|
||||
return cast<CompoundStmt>(getStmts()[0]);
|
||||
}
|
||||
const CompoundStmt *getTryBlock() const {
|
||||
return cast<CompoundStmt>(getStmts()[0]);
|
||||
}
|
||||
|
||||
unsigned getNumHandlers() const { return NumHandlers; }
|
||||
CXXCatchStmt *getHandler(unsigned i) {
|
||||
return cast<CXXCatchStmt>(getStmts()[i + 1]);
|
||||
}
|
||||
const CXXCatchStmt *getHandler(unsigned i) const {
|
||||
return cast<CXXCatchStmt>(getStmts()[i + 1]);
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXTryStmtClass;
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
|
||||
}
|
||||
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
|
||||
/// statement, represented as 'for (range-declarator : range-expression)'.
|
||||
///
|
||||
/// This is stored in a partially-desugared form to allow full semantic
|
||||
/// analysis of the constituent components. The original syntactic components
|
||||
/// can be extracted using getLoopVariable and getRangeInit.
|
||||
class CXXForRangeStmt : public Stmt {
|
||||
enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
|
||||
// SubExprs[RANGE] is an expression or declstmt.
|
||||
// SubExprs[COND] and SubExprs[INC] are expressions.
|
||||
Stmt *SubExprs[END];
|
||||
SourceLocation ForLoc;
|
||||
SourceLocation ColonLoc;
|
||||
SourceLocation RParenLoc;
|
||||
public:
|
||||
CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
|
||||
Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
|
||||
SourceLocation FL, SourceLocation CL, SourceLocation RPL);
|
||||
CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
|
||||
|
||||
|
||||
VarDecl *getLoopVariable();
|
||||
Expr *getRangeInit();
|
||||
|
||||
const VarDecl *getLoopVariable() const;
|
||||
const Expr *getRangeInit() const;
|
||||
|
||||
|
||||
DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
|
||||
DeclStmt *getBeginEndStmt() {
|
||||
return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
|
||||
}
|
||||
Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
|
||||
Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
|
||||
DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
|
||||
Stmt *getBody() { return SubExprs[BODY]; }
|
||||
|
||||
const DeclStmt *getRangeStmt() const {
|
||||
return cast<DeclStmt>(SubExprs[RANGE]);
|
||||
}
|
||||
const DeclStmt *getBeginEndStmt() const {
|
||||
return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
|
||||
}
|
||||
const Expr *getCond() const {
|
||||
return cast_or_null<Expr>(SubExprs[COND]);
|
||||
}
|
||||
const Expr *getInc() const {
|
||||
return cast_or_null<Expr>(SubExprs[INC]);
|
||||
}
|
||||
const DeclStmt *getLoopVarStmt() const {
|
||||
return cast<DeclStmt>(SubExprs[LOOPVAR]);
|
||||
}
|
||||
const Stmt *getBody() const { return SubExprs[BODY]; }
|
||||
|
||||
void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
|
||||
void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
|
||||
void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
|
||||
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
|
||||
void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
|
||||
void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
|
||||
void setBody(Stmt *S) { SubExprs[BODY] = S; }
|
||||
|
||||
|
||||
SourceLocation getForLoc() const { return ForLoc; }
|
||||
void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
|
||||
SourceLocation getColonLoc() const { return ColonLoc; }
|
||||
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return SubExprs[BODY]->getLocEnd();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXForRangeStmtClass;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[END]);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Representation of a Microsoft __if_exists or __if_not_exists
|
||||
/// statement with a dependent name.
|
||||
///
|
||||
/// The __if_exists statement can be used to include a sequence of statements
|
||||
/// in the program only when a particular dependent name does not exist. For
|
||||
/// example:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T>
|
||||
/// void call_foo(T &t) {
|
||||
/// __if_exists (T::foo) {
|
||||
/// t.foo(); // okay: only called when T::foo exists.
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// Similarly, the __if_not_exists statement can be used to include the
|
||||
/// statements when a particular name does not exist.
|
||||
///
|
||||
/// Note that this statement only captures __if_exists and __if_not_exists
|
||||
/// statements whose name is dependent. All non-dependent cases are handled
|
||||
/// directly in the parser, so that they don't introduce a new scope. Clang
|
||||
/// introduces scopes in the dependent case to keep names inside the compound
|
||||
/// statement from leaking out into the surround statements, which would
|
||||
/// compromise the template instantiation model. This behavior differs from
|
||||
/// Visual C++ (which never introduces a scope), but is a fairly reasonable
|
||||
/// approximation of the VC++ behavior.
|
||||
class MSDependentExistsStmt : public Stmt {
|
||||
SourceLocation KeywordLoc;
|
||||
bool IsIfExists;
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
DeclarationNameInfo NameInfo;
|
||||
Stmt *SubStmt;
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
|
||||
public:
|
||||
MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
DeclarationNameInfo NameInfo,
|
||||
CompoundStmt *SubStmt)
|
||||
: Stmt(MSDependentExistsStmtClass),
|
||||
KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
|
||||
QualifierLoc(QualifierLoc), NameInfo(NameInfo),
|
||||
SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
|
||||
|
||||
/// \brief Retrieve the location of the __if_exists or __if_not_exists
|
||||
/// keyword.
|
||||
SourceLocation getKeywordLoc() const { return KeywordLoc; }
|
||||
|
||||
/// \brief Determine whether this is an __if_exists statement.
|
||||
bool isIfExists() const { return IsIfExists; }
|
||||
|
||||
/// \brief Determine whether this is an __if_exists statement.
|
||||
bool isIfNotExists() const { return !IsIfExists; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies this name, if
|
||||
/// any.
|
||||
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
|
||||
|
||||
/// \brief Retrieve the name of the entity we're testing for, along with
|
||||
/// location information
|
||||
DeclarationNameInfo getNameInfo() const { return NameInfo; }
|
||||
|
||||
/// \brief Retrieve the compound statement that will be included in the
|
||||
/// program only if the existence of the symbol matches the initial keyword.
|
||||
CompoundStmt *getSubStmt() const {
|
||||
return reinterpret_cast<CompoundStmt *>(SubStmt);
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
|
||||
|
||||
child_range children() {
|
||||
return child_range(&SubStmt, &SubStmt+1);
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == MSDependentExistsStmtClass;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
83
thirdparty/clang/include/clang/AST/StmtGraphTraits.h
vendored
Normal file
83
thirdparty/clang/include/clang/AST/StmtGraphTraits.h
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a template specialization of llvm::GraphTraits to
|
||||
// treat ASTs (Stmt*) as graphs
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
|
||||
#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
|
||||
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//template <typename T> struct GraphTraits;
|
||||
|
||||
|
||||
template <> struct GraphTraits<clang::Stmt*> {
|
||||
typedef clang::Stmt NodeType;
|
||||
typedef clang::Stmt::child_iterator ChildIteratorType;
|
||||
typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
|
||||
|
||||
static NodeType* getEntryNode(clang::Stmt* S) { return S; }
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType* N) {
|
||||
if (N) return N->child_begin();
|
||||
else return ChildIteratorType();
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType* N) {
|
||||
if (N) return N->child_end();
|
||||
else return ChildIteratorType();
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_begin(clang::Stmt* S) {
|
||||
return df_begin(S);
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end(clang::Stmt* S) {
|
||||
return df_end(S);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <> struct GraphTraits<const clang::Stmt*> {
|
||||
typedef const clang::Stmt NodeType;
|
||||
typedef clang::Stmt::const_child_iterator ChildIteratorType;
|
||||
typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
|
||||
|
||||
static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType* N) {
|
||||
if (N) return N->child_begin();
|
||||
else return ChildIteratorType();
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType* N) {
|
||||
if (N) return N->child_end();
|
||||
else return ChildIteratorType();
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_begin(const clang::Stmt* S) {
|
||||
return df_begin(S);
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end(const clang::Stmt* S) {
|
||||
return df_end(S);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
230
thirdparty/clang/include/clang/AST/StmtIterator.h
vendored
Normal file
230
thirdparty/clang/include/clang/AST/StmtIterator.h
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
//===--- StmtIterator.h - Iterators for Statements --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the StmtIterator and ConstStmtIterator classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_STMT_ITR_H
|
||||
#define LLVM_CLANG_AST_STMT_ITR_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class Stmt;
|
||||
class Decl;
|
||||
class VariableArrayType;
|
||||
|
||||
class StmtIteratorBase {
|
||||
protected:
|
||||
enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3,
|
||||
Flags = 0x3 };
|
||||
|
||||
Stmt **stmt;
|
||||
union { Decl *decl; Decl **DGI; };
|
||||
uintptr_t RawVAPtr;
|
||||
Decl **DGE;
|
||||
|
||||
bool inDecl() const {
|
||||
return (RawVAPtr & Flags) == DeclMode;
|
||||
}
|
||||
|
||||
bool inDeclGroup() const {
|
||||
return (RawVAPtr & Flags) == DeclGroupMode;
|
||||
}
|
||||
|
||||
bool inSizeOfTypeVA() const {
|
||||
return (RawVAPtr & Flags) == SizeOfTypeVAMode;
|
||||
}
|
||||
|
||||
bool inStmt() const {
|
||||
return (RawVAPtr & Flags) == 0;
|
||||
}
|
||||
|
||||
const VariableArrayType *getVAPtr() const {
|
||||
return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
|
||||
}
|
||||
|
||||
void setVAPtr(const VariableArrayType *P) {
|
||||
assert (inDecl() || inDeclGroup() || inSizeOfTypeVA());
|
||||
RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
|
||||
}
|
||||
|
||||
void NextDecl(bool ImmediateAdvance = true);
|
||||
bool HandleDecl(Decl* D);
|
||||
void NextVA();
|
||||
|
||||
Stmt*& GetDeclExpr() const;
|
||||
|
||||
StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {}
|
||||
StmtIteratorBase(Decl *d, Stmt **s);
|
||||
StmtIteratorBase(const VariableArrayType *t);
|
||||
StmtIteratorBase(Decl **dgi, Decl **dge);
|
||||
StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {}
|
||||
};
|
||||
|
||||
|
||||
template <typename DERIVED, typename REFERENCE>
|
||||
class StmtIteratorImpl : public StmtIteratorBase,
|
||||
public std::iterator<std::forward_iterator_tag,
|
||||
REFERENCE, ptrdiff_t,
|
||||
REFERENCE, REFERENCE> {
|
||||
protected:
|
||||
StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
|
||||
public:
|
||||
StmtIteratorImpl() {}
|
||||
StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
|
||||
StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
|
||||
StmtIteratorImpl(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {}
|
||||
StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
|
||||
|
||||
DERIVED& operator++() {
|
||||
if (inStmt())
|
||||
++stmt;
|
||||
else if (getVAPtr())
|
||||
NextVA();
|
||||
else
|
||||
NextDecl();
|
||||
|
||||
return static_cast<DERIVED&>(*this);
|
||||
}
|
||||
|
||||
DERIVED operator++(int) {
|
||||
DERIVED tmp = static_cast<DERIVED&>(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const DERIVED& RHS) const {
|
||||
return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr;
|
||||
}
|
||||
|
||||
bool operator!=(const DERIVED& RHS) const {
|
||||
return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr;
|
||||
}
|
||||
|
||||
REFERENCE operator*() const {
|
||||
return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr());
|
||||
}
|
||||
|
||||
REFERENCE operator->() const { return operator*(); }
|
||||
};
|
||||
|
||||
struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
|
||||
explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
|
||||
|
||||
StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
|
||||
|
||||
StmtIterator(Decl** dgi, Decl** dge)
|
||||
: StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
|
||||
|
||||
StmtIterator(const VariableArrayType *t)
|
||||
: StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
|
||||
|
||||
StmtIterator(Decl* D, Stmt **s = 0)
|
||||
: StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {}
|
||||
};
|
||||
|
||||
struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
|
||||
const Stmt*> {
|
||||
explicit ConstStmtIterator() :
|
||||
StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
|
||||
|
||||
ConstStmtIterator(const StmtIterator& RHS) :
|
||||
StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
|
||||
};
|
||||
|
||||
/// A range of statement iterators.
|
||||
///
|
||||
/// This class provides some extra functionality beyond std::pair
|
||||
/// in order to allow the following idiom:
|
||||
/// for (StmtRange range = stmt->children(); range; ++range)
|
||||
struct StmtRange : std::pair<StmtIterator,StmtIterator> {
|
||||
StmtRange() {}
|
||||
StmtRange(const StmtIterator &begin, const StmtIterator &end)
|
||||
: std::pair<StmtIterator,StmtIterator>(begin, end) {}
|
||||
|
||||
bool empty() const { return first == second; }
|
||||
operator bool() const { return !empty(); }
|
||||
|
||||
Stmt *operator->() const { return first.operator->(); }
|
||||
Stmt *&operator*() const { return first.operator*(); }
|
||||
|
||||
StmtRange &operator++() {
|
||||
assert(!empty() && "incrementing on empty range");
|
||||
++first;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StmtRange operator++(int) {
|
||||
assert(!empty() && "incrementing on empty range");
|
||||
StmtRange copy = *this;
|
||||
++first;
|
||||
return copy;
|
||||
}
|
||||
|
||||
friend const StmtIterator &begin(const StmtRange &range) {
|
||||
return range.first;
|
||||
}
|
||||
friend const StmtIterator &end(const StmtRange &range) {
|
||||
return range.second;
|
||||
}
|
||||
};
|
||||
|
||||
/// A range of const statement iterators.
|
||||
///
|
||||
/// This class provides some extra functionality beyond std::pair
|
||||
/// in order to allow the following idiom:
|
||||
/// for (ConstStmtRange range = stmt->children(); range; ++range)
|
||||
struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> {
|
||||
ConstStmtRange() {}
|
||||
ConstStmtRange(const ConstStmtIterator &begin,
|
||||
const ConstStmtIterator &end)
|
||||
: std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
|
||||
ConstStmtRange(const StmtRange &range)
|
||||
: std::pair<ConstStmtIterator,ConstStmtIterator>(range.first, range.second)
|
||||
{}
|
||||
ConstStmtRange(const StmtIterator &begin, const StmtIterator &end)
|
||||
: std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
|
||||
|
||||
bool empty() const { return first == second; }
|
||||
operator bool() const { return !empty(); }
|
||||
|
||||
const Stmt *operator->() const { return first.operator->(); }
|
||||
const Stmt *operator*() const { return first.operator*(); }
|
||||
|
||||
ConstStmtRange &operator++() {
|
||||
assert(!empty() && "incrementing on empty range");
|
||||
++first;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConstStmtRange operator++(int) {
|
||||
assert(!empty() && "incrementing on empty range");
|
||||
ConstStmtRange copy = *this;
|
||||
++first;
|
||||
return copy;
|
||||
}
|
||||
|
||||
friend const ConstStmtIterator &begin(const ConstStmtRange &range) {
|
||||
return range.first;
|
||||
}
|
||||
friend const ConstStmtIterator &end(const ConstStmtRange &range) {
|
||||
return range.second;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
375
thirdparty/clang/include/clang/AST/StmtObjC.h
vendored
Normal file
375
thirdparty/clang/include/clang/AST/StmtObjC.h
vendored
Normal file
@@ -0,0 +1,375 @@
|
||||
//===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// \file
|
||||
/// \brief Defines the Objective-C statement AST node classes.
|
||||
|
||||
#ifndef LLVM_CLANG_AST_STMTOBJC_H
|
||||
#define LLVM_CLANG_AST_STMTOBJC_H
|
||||
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief Represents Objective-C's collection statement.
|
||||
///
|
||||
/// This is represented as 'for (element 'in' collection-expression)' stmt.
|
||||
class ObjCForCollectionStmt : public Stmt {
|
||||
enum { ELEM, COLLECTION, BODY, END_EXPR };
|
||||
Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
|
||||
SourceLocation ForLoc;
|
||||
SourceLocation RParenLoc;
|
||||
public:
|
||||
ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
|
||||
SourceLocation FCL, SourceLocation RPL);
|
||||
explicit ObjCForCollectionStmt(EmptyShell Empty) :
|
||||
Stmt(ObjCForCollectionStmtClass, Empty) { }
|
||||
|
||||
Stmt *getElement() { return SubExprs[ELEM]; }
|
||||
Expr *getCollection() {
|
||||
return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
|
||||
}
|
||||
Stmt *getBody() { return SubExprs[BODY]; }
|
||||
|
||||
const Stmt *getElement() const { return SubExprs[ELEM]; }
|
||||
const Expr *getCollection() const {
|
||||
return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
|
||||
}
|
||||
const Stmt *getBody() const { return SubExprs[BODY]; }
|
||||
|
||||
void setElement(Stmt *S) { SubExprs[ELEM] = S; }
|
||||
void setCollection(Expr *E) {
|
||||
SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
|
||||
}
|
||||
void setBody(Stmt *S) { SubExprs[BODY] = S; }
|
||||
|
||||
SourceLocation getForLoc() const { return ForLoc; }
|
||||
void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return SubExprs[BODY]->getLocEnd();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCForCollectionStmtClass;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents Objective-C's \@catch statement.
|
||||
class ObjCAtCatchStmt : public Stmt {
|
||||
private:
|
||||
VarDecl *ExceptionDecl;
|
||||
Stmt *Body;
|
||||
SourceLocation AtCatchLoc, RParenLoc;
|
||||
|
||||
public:
|
||||
ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
|
||||
VarDecl *catchVarDecl,
|
||||
Stmt *atCatchStmt)
|
||||
: Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl),
|
||||
Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
|
||||
|
||||
explicit ObjCAtCatchStmt(EmptyShell Empty) :
|
||||
Stmt(ObjCAtCatchStmtClass, Empty) { }
|
||||
|
||||
const Stmt *getCatchBody() const { return Body; }
|
||||
Stmt *getCatchBody() { return Body; }
|
||||
void setCatchBody(Stmt *S) { Body = S; }
|
||||
|
||||
const VarDecl *getCatchParamDecl() const {
|
||||
return ExceptionDecl;
|
||||
}
|
||||
VarDecl *getCatchParamDecl() {
|
||||
return ExceptionDecl;
|
||||
}
|
||||
void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
|
||||
|
||||
SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
|
||||
void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
|
||||
|
||||
bool hasEllipsis() const { return getCatchParamDecl() == 0; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAtCatchStmtClass;
|
||||
}
|
||||
|
||||
child_range children() { return child_range(&Body, &Body + 1); }
|
||||
};
|
||||
|
||||
/// \brief Represents Objective-C's \@finally statement
|
||||
class ObjCAtFinallyStmt : public Stmt {
|
||||
Stmt *AtFinallyStmt;
|
||||
SourceLocation AtFinallyLoc;
|
||||
public:
|
||||
ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
|
||||
: Stmt(ObjCAtFinallyStmtClass),
|
||||
AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
|
||||
|
||||
explicit ObjCAtFinallyStmt(EmptyShell Empty) :
|
||||
Stmt(ObjCAtFinallyStmtClass, Empty) { }
|
||||
|
||||
const Stmt *getFinallyBody() const { return AtFinallyStmt; }
|
||||
Stmt *getFinallyBody() { return AtFinallyStmt; }
|
||||
void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return AtFinallyLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return AtFinallyStmt->getLocEnd();
|
||||
}
|
||||
|
||||
SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
|
||||
void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAtFinallyStmtClass;
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents Objective-C's \@try ... \@catch ... \@finally statement.
|
||||
class ObjCAtTryStmt : public Stmt {
|
||||
private:
|
||||
// The location of the @ in the \@try.
|
||||
SourceLocation AtTryLoc;
|
||||
|
||||
// The number of catch blocks in this statement.
|
||||
unsigned NumCatchStmts : 16;
|
||||
|
||||
// Whether this statement has a \@finally statement.
|
||||
bool HasFinally : 1;
|
||||
|
||||
/// \brief Retrieve the statements that are stored after this \@try statement.
|
||||
///
|
||||
/// The order of the statements in memory follows the order in the source,
|
||||
/// with the \@try body first, followed by the \@catch statements (if any)
|
||||
/// and, finally, the \@finally (if it exists).
|
||||
Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
|
||||
const Stmt* const *getStmts() const {
|
||||
return reinterpret_cast<const Stmt * const*> (this + 1);
|
||||
}
|
||||
|
||||
ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
|
||||
Stmt **CatchStmts, unsigned NumCatchStmts,
|
||||
Stmt *atFinallyStmt);
|
||||
|
||||
explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
|
||||
bool HasFinally)
|
||||
: Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
|
||||
HasFinally(HasFinally) { }
|
||||
|
||||
public:
|
||||
static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc,
|
||||
Stmt *atTryStmt,
|
||||
Stmt **CatchStmts, unsigned NumCatchStmts,
|
||||
Stmt *atFinallyStmt);
|
||||
static ObjCAtTryStmt *CreateEmpty(ASTContext &Context,
|
||||
unsigned NumCatchStmts,
|
||||
bool HasFinally);
|
||||
|
||||
/// \brief Retrieve the location of the @ in the \@try.
|
||||
SourceLocation getAtTryLoc() const { return AtTryLoc; }
|
||||
void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
|
||||
|
||||
/// \brief Retrieve the \@try body.
|
||||
const Stmt *getTryBody() const { return getStmts()[0]; }
|
||||
Stmt *getTryBody() { return getStmts()[0]; }
|
||||
void setTryBody(Stmt *S) { getStmts()[0] = S; }
|
||||
|
||||
/// \brief Retrieve the number of \@catch statements in this try-catch-finally
|
||||
/// block.
|
||||
unsigned getNumCatchStmts() const { return NumCatchStmts; }
|
||||
|
||||
/// \brief Retrieve a \@catch statement.
|
||||
const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
|
||||
assert(I < NumCatchStmts && "Out-of-bounds @catch index");
|
||||
return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
|
||||
}
|
||||
|
||||
/// \brief Retrieve a \@catch statement.
|
||||
ObjCAtCatchStmt *getCatchStmt(unsigned I) {
|
||||
assert(I < NumCatchStmts && "Out-of-bounds @catch index");
|
||||
return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
|
||||
}
|
||||
|
||||
/// \brief Set a particular catch statement.
|
||||
void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
|
||||
assert(I < NumCatchStmts && "Out-of-bounds @catch index");
|
||||
getStmts()[I + 1] = S;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the \@finally statement, if any.
|
||||
const ObjCAtFinallyStmt *getFinallyStmt() const {
|
||||
if (!HasFinally)
|
||||
return 0;
|
||||
|
||||
return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
|
||||
}
|
||||
ObjCAtFinallyStmt *getFinallyStmt() {
|
||||
if (!HasFinally)
|
||||
return 0;
|
||||
|
||||
return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
|
||||
}
|
||||
void setFinallyStmt(Stmt *S) {
|
||||
assert(HasFinally && "@try does not have a @finally slot!");
|
||||
getStmts()[1 + NumCatchStmts] = S;
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return AtTryLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY;
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAtTryStmtClass;
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(getStmts(),
|
||||
getStmts() + 1 + NumCatchStmts + HasFinally);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents Objective-C's \@synchronized statement.
|
||||
///
|
||||
/// Example:
|
||||
/// \code
|
||||
/// @synchronized (sem) {
|
||||
/// do-something;
|
||||
/// }
|
||||
/// \endcode
|
||||
class ObjCAtSynchronizedStmt : public Stmt {
|
||||
private:
|
||||
enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
|
||||
Stmt* SubStmts[END_EXPR];
|
||||
SourceLocation AtSynchronizedLoc;
|
||||
|
||||
public:
|
||||
ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
|
||||
Stmt *synchBody)
|
||||
: Stmt(ObjCAtSynchronizedStmtClass) {
|
||||
SubStmts[SYNC_EXPR] = synchExpr;
|
||||
SubStmts[SYNC_BODY] = synchBody;
|
||||
AtSynchronizedLoc = atSynchronizedLoc;
|
||||
}
|
||||
explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
|
||||
Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
|
||||
|
||||
SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
|
||||
void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
|
||||
|
||||
const CompoundStmt *getSynchBody() const {
|
||||
return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
|
||||
}
|
||||
CompoundStmt *getSynchBody() {
|
||||
return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
|
||||
}
|
||||
void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
|
||||
|
||||
const Expr *getSynchExpr() const {
|
||||
return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
|
||||
}
|
||||
Expr *getSynchExpr() {
|
||||
return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
|
||||
}
|
||||
void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return AtSynchronizedLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return getSynchBody()->getLocEnd();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents Objective-C's \@throw statement.
|
||||
class ObjCAtThrowStmt : public Stmt {
|
||||
Stmt *Throw;
|
||||
SourceLocation AtThrowLoc;
|
||||
public:
|
||||
ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
|
||||
: Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
|
||||
AtThrowLoc = atThrowLoc;
|
||||
}
|
||||
explicit ObjCAtThrowStmt(EmptyShell Empty) :
|
||||
Stmt(ObjCAtThrowStmtClass, Empty) { }
|
||||
|
||||
const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
|
||||
Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
|
||||
void setThrowExpr(Stmt *S) { Throw = S; }
|
||||
|
||||
SourceLocation getThrowLoc() { return AtThrowLoc; }
|
||||
void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return Throw ? Throw->getLocEnd() : AtThrowLoc;
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAtThrowStmtClass;
|
||||
}
|
||||
|
||||
child_range children() { return child_range(&Throw, &Throw+1); }
|
||||
};
|
||||
|
||||
/// \brief Represents Objective-C's \@autoreleasepool Statement
|
||||
class ObjCAutoreleasePoolStmt : public Stmt {
|
||||
Stmt *SubStmt;
|
||||
SourceLocation AtLoc;
|
||||
public:
|
||||
ObjCAutoreleasePoolStmt(SourceLocation atLoc,
|
||||
Stmt *subStmt)
|
||||
: Stmt(ObjCAutoreleasePoolStmtClass),
|
||||
SubStmt(subStmt), AtLoc(atLoc) {}
|
||||
|
||||
explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
|
||||
Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
|
||||
|
||||
const Stmt *getSubStmt() const { return SubStmt; }
|
||||
Stmt *getSubStmt() { return SubStmt; }
|
||||
void setSubStmt(Stmt *S) { SubStmt = S; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
|
||||
|
||||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
|
||||
}
|
||||
|
||||
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
189
thirdparty/clang/include/clang/AST/StmtVisitor.h
vendored
Normal file
189
thirdparty/clang/include/clang/AST/StmtVisitor.h
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the StmtVisitor and ConstStmtVisitor interfaces.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_STMTVISITOR_H
|
||||
#define LLVM_CLANG_AST_STMTVISITOR_H
|
||||
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/AST/StmtObjC.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
template <typename T> struct make_ptr { typedef T *type; };
|
||||
template <typename T> struct make_const_ptr { typedef const T *type; };
|
||||
|
||||
/// StmtVisitorBase - This class implements a simple visitor for Stmt
|
||||
/// subclasses. Since Expr derives from Stmt, this also includes support for
|
||||
/// visiting Exprs.
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
class StmtVisitorBase {
|
||||
public:
|
||||
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(NAME, CLASS) \
|
||||
return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
|
||||
|
||||
RetTy Visit(PTR(Stmt) S) {
|
||||
|
||||
// If we have a binary expr, dispatch to the subcode of the binop. A smart
|
||||
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
|
||||
// below.
|
||||
if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) {
|
||||
switch (BinOp->getOpcode()) {
|
||||
case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator);
|
||||
case BO_PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator);
|
||||
case BO_Mul: DISPATCH(BinMul, BinaryOperator);
|
||||
case BO_Div: DISPATCH(BinDiv, BinaryOperator);
|
||||
case BO_Rem: DISPATCH(BinRem, BinaryOperator);
|
||||
case BO_Add: DISPATCH(BinAdd, BinaryOperator);
|
||||
case BO_Sub: DISPATCH(BinSub, BinaryOperator);
|
||||
case BO_Shl: DISPATCH(BinShl, BinaryOperator);
|
||||
case BO_Shr: DISPATCH(BinShr, BinaryOperator);
|
||||
|
||||
case BO_LT: DISPATCH(BinLT, BinaryOperator);
|
||||
case BO_GT: DISPATCH(BinGT, BinaryOperator);
|
||||
case BO_LE: DISPATCH(BinLE, BinaryOperator);
|
||||
case BO_GE: DISPATCH(BinGE, BinaryOperator);
|
||||
case BO_EQ: DISPATCH(BinEQ, BinaryOperator);
|
||||
case BO_NE: DISPATCH(BinNE, BinaryOperator);
|
||||
|
||||
case BO_And: DISPATCH(BinAnd, BinaryOperator);
|
||||
case BO_Xor: DISPATCH(BinXor, BinaryOperator);
|
||||
case BO_Or : DISPATCH(BinOr, BinaryOperator);
|
||||
case BO_LAnd: DISPATCH(BinLAnd, BinaryOperator);
|
||||
case BO_LOr : DISPATCH(BinLOr, BinaryOperator);
|
||||
case BO_Assign: DISPATCH(BinAssign, BinaryOperator);
|
||||
case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
|
||||
case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
|
||||
case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
|
||||
case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
|
||||
case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
|
||||
case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
|
||||
case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
|
||||
case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
|
||||
case BO_OrAssign: DISPATCH(BinOrAssign, CompoundAssignOperator);
|
||||
case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
|
||||
case BO_Comma: DISPATCH(BinComma, BinaryOperator);
|
||||
}
|
||||
} else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) {
|
||||
switch (UnOp->getOpcode()) {
|
||||
case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
|
||||
case UO_PostDec: DISPATCH(UnaryPostDec, UnaryOperator);
|
||||
case UO_PreInc: DISPATCH(UnaryPreInc, UnaryOperator);
|
||||
case UO_PreDec: DISPATCH(UnaryPreDec, UnaryOperator);
|
||||
case UO_AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator);
|
||||
case UO_Deref: DISPATCH(UnaryDeref, UnaryOperator);
|
||||
case UO_Plus: DISPATCH(UnaryPlus, UnaryOperator);
|
||||
case UO_Minus: DISPATCH(UnaryMinus, UnaryOperator);
|
||||
case UO_Not: DISPATCH(UnaryNot, UnaryOperator);
|
||||
case UO_LNot: DISPATCH(UnaryLNot, UnaryOperator);
|
||||
case UO_Real: DISPATCH(UnaryReal, UnaryOperator);
|
||||
case UO_Imag: DISPATCH(UnaryImag, UnaryOperator);
|
||||
case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator);
|
||||
}
|
||||
}
|
||||
|
||||
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
|
||||
switch (S->getStmtClass()) {
|
||||
default: llvm_unreachable("Unknown stmt kind!");
|
||||
#define ABSTRACT_STMT(STMT)
|
||||
#define STMT(CLASS, PARENT) \
|
||||
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
|
||||
#include "clang/AST/StmtNodes.inc"
|
||||
}
|
||||
}
|
||||
|
||||
// If the implementation chooses not to implement a certain visit method, fall
|
||||
// back on VisitExpr or whatever else is the superclass.
|
||||
#define STMT(CLASS, PARENT) \
|
||||
RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
|
||||
#include "clang/AST/StmtNodes.inc"
|
||||
|
||||
// If the implementation doesn't implement binary operator methods, fall back
|
||||
// on VisitBinaryOperator.
|
||||
#define BINOP_FALLBACK(NAME) \
|
||||
RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
|
||||
DISPATCH(BinaryOperator, BinaryOperator); \
|
||||
}
|
||||
BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
|
||||
BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem)
|
||||
BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl)
|
||||
BINOP_FALLBACK(Shr)
|
||||
|
||||
BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
|
||||
BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
|
||||
BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
|
||||
BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
|
||||
|
||||
BINOP_FALLBACK(Assign)
|
||||
BINOP_FALLBACK(Comma)
|
||||
#undef BINOP_FALLBACK
|
||||
|
||||
// If the implementation doesn't implement compound assignment operator
|
||||
// methods, fall back on VisitCompoundAssignOperator.
|
||||
#define CAO_FALLBACK(NAME) \
|
||||
RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
|
||||
DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
|
||||
}
|
||||
CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
|
||||
CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
|
||||
CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
|
||||
CAO_FALLBACK(XorAssign)
|
||||
#undef CAO_FALLBACK
|
||||
|
||||
// If the implementation doesn't implement unary operator methods, fall back
|
||||
// on VisitUnaryOperator.
|
||||
#define UNARYOP_FALLBACK(NAME) \
|
||||
RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
|
||||
DISPATCH(UnaryOperator, UnaryOperator); \
|
||||
}
|
||||
UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
|
||||
UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec)
|
||||
UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref)
|
||||
|
||||
UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
|
||||
UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
|
||||
UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
|
||||
UNARYOP_FALLBACK(Extension)
|
||||
#undef UNARYOP_FALLBACK
|
||||
|
||||
// Base case, ignore it. :)
|
||||
RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
|
||||
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
|
||||
/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
|
||||
///
|
||||
/// This class does not preserve constness of Stmt pointers (see also
|
||||
/// ConstStmtVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class StmtVisitor
|
||||
: public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
|
||||
|
||||
/// ConstStmtVisitor - This class implements a simple visitor for Stmt
|
||||
/// subclasses. Since Expr derives from Stmt, this also includes support for
|
||||
/// visiting Exprs.
|
||||
///
|
||||
/// This class preserves constness of Stmt pointers (see also StmtVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class ConstStmtVisitor
|
||||
: public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
659
thirdparty/clang/include/clang/AST/TemplateBase.h
vendored
Normal file
659
thirdparty/clang/include/clang/AST/TemplateBase.h
vendored
Normal file
@@ -0,0 +1,659 @@
|
||||
//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides definitions which are common for all kinds of
|
||||
// template representation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
|
||||
#define LLVM_CLANG_AST_TEMPLATEBASE_H
|
||||
|
||||
#include "clang/AST/TemplateName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace llvm {
|
||||
class FoldingSetNodeID;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
|
||||
class DiagnosticBuilder;
|
||||
class Expr;
|
||||
struct PrintingPolicy;
|
||||
class TypeSourceInfo;
|
||||
class ValueDecl;
|
||||
|
||||
/// \brief Represents a template argument within a class template
|
||||
/// specialization.
|
||||
class TemplateArgument {
|
||||
public:
|
||||
/// \brief The kind of template argument we're storing.
|
||||
enum ArgKind {
|
||||
/// \brief Represents an empty template argument, e.g., one that has not
|
||||
/// been deduced.
|
||||
Null = 0,
|
||||
/// The template argument is a type.
|
||||
Type,
|
||||
/// The template argument is a declaration that was provided for a pointer,
|
||||
/// reference, or pointer to member non-type template parameter.
|
||||
Declaration,
|
||||
/// The template argument is a null pointer or null pointer to member that
|
||||
/// was provided for a non-type template parameter.
|
||||
NullPtr,
|
||||
/// The template argument is an integral value stored in an llvm::APSInt
|
||||
/// that was provided for an integral non-type template parameter.
|
||||
Integral,
|
||||
/// The template argument is a template name that was provided for a
|
||||
/// template template parameter.
|
||||
Template,
|
||||
/// The template argument is a pack expansion of a template name that was
|
||||
/// provided for a template template parameter.
|
||||
TemplateExpansion,
|
||||
/// The template argument is a value- or type-dependent expression
|
||||
/// stored in an Expr*.
|
||||
Expression,
|
||||
/// The template argument is actually a parameter pack. Arguments are stored
|
||||
/// in the Args struct.
|
||||
Pack
|
||||
};
|
||||
|
||||
private:
|
||||
/// \brief The kind of template argument we're storing.
|
||||
unsigned Kind;
|
||||
|
||||
struct DA {
|
||||
ValueDecl *D;
|
||||
bool ForRefParam;
|
||||
};
|
||||
struct I {
|
||||
// We store a decomposed APSInt with the data allocated by ASTContext if
|
||||
// BitWidth > 64. The memory may be shared between multiple
|
||||
// TemplateArgument instances.
|
||||
union {
|
||||
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
|
||||
const uint64_t *pVal; ///< Used to store the >64 bits integer value.
|
||||
};
|
||||
unsigned BitWidth : 31;
|
||||
unsigned IsUnsigned : 1;
|
||||
void *Type;
|
||||
};
|
||||
struct A {
|
||||
const TemplateArgument *Args;
|
||||
unsigned NumArgs;
|
||||
};
|
||||
struct TA {
|
||||
void *Name;
|
||||
unsigned NumExpansions;
|
||||
};
|
||||
union {
|
||||
struct DA DeclArg;
|
||||
struct I Integer;
|
||||
struct A Args;
|
||||
struct TA TemplateArg;
|
||||
uintptr_t TypeOrValue;
|
||||
};
|
||||
|
||||
TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
|
||||
|
||||
public:
|
||||
/// \brief Construct an empty, invalid template argument.
|
||||
TemplateArgument() : Kind(Null), TypeOrValue(0) { }
|
||||
|
||||
/// \brief Construct a template type argument.
|
||||
TemplateArgument(QualType T, bool isNullPtr = false)
|
||||
: Kind(isNullPtr ? NullPtr : Type) {
|
||||
TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
|
||||
}
|
||||
|
||||
/// \brief Construct a template argument that refers to a
|
||||
/// declaration, which is either an external declaration or a
|
||||
/// template declaration.
|
||||
TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) {
|
||||
assert(D && "Expected decl");
|
||||
DeclArg.D = D;
|
||||
DeclArg.ForRefParam = ForRefParam;
|
||||
}
|
||||
|
||||
/// \brief Construct an integral constant template argument. The memory to
|
||||
/// store the value is allocated with Ctx.
|
||||
TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
|
||||
|
||||
/// \brief Construct an integral constant template argument with the same
|
||||
/// value as Other but a different type.
|
||||
TemplateArgument(const TemplateArgument &Other, QualType Type)
|
||||
: Kind(Integral) {
|
||||
Integer = Other.Integer;
|
||||
Integer.Type = Type.getAsOpaquePtr();
|
||||
}
|
||||
|
||||
/// \brief Construct a template argument that is a template.
|
||||
///
|
||||
/// This form of template argument is generally used for template template
|
||||
/// parameters. However, the template name could be a dependent template
|
||||
/// name that ends up being instantiated to a function template whose address
|
||||
/// is taken.
|
||||
///
|
||||
/// \param Name The template name.
|
||||
TemplateArgument(TemplateName Name) : Kind(Template)
|
||||
{
|
||||
TemplateArg.Name = Name.getAsVoidPointer();
|
||||
TemplateArg.NumExpansions = 0;
|
||||
}
|
||||
|
||||
/// \brief Construct a template argument that is a template pack expansion.
|
||||
///
|
||||
/// This form of template argument is generally used for template template
|
||||
/// parameters. However, the template name could be a dependent template
|
||||
/// name that ends up being instantiated to a function template whose address
|
||||
/// is taken.
|
||||
///
|
||||
/// \param Name The template name.
|
||||
///
|
||||
/// \param NumExpansions The number of expansions that will be generated by
|
||||
/// instantiating
|
||||
TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions)
|
||||
: Kind(TemplateExpansion)
|
||||
{
|
||||
TemplateArg.Name = Name.getAsVoidPointer();
|
||||
if (NumExpansions)
|
||||
TemplateArg.NumExpansions = *NumExpansions + 1;
|
||||
else
|
||||
TemplateArg.NumExpansions = 0;
|
||||
}
|
||||
|
||||
/// \brief Construct a template argument that is an expression.
|
||||
///
|
||||
/// This form of template argument only occurs in template argument
|
||||
/// lists used for dependent types and for expression; it will not
|
||||
/// occur in a non-dependent, canonical template argument list.
|
||||
TemplateArgument(Expr *E) : Kind(Expression) {
|
||||
TypeOrValue = reinterpret_cast<uintptr_t>(E);
|
||||
}
|
||||
|
||||
/// \brief Construct a template argument that is a template argument pack.
|
||||
///
|
||||
/// We assume that storage for the template arguments provided
|
||||
/// outlives the TemplateArgument itself.
|
||||
TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){
|
||||
this->Args.Args = Args;
|
||||
this->Args.NumArgs = NumArgs;
|
||||
}
|
||||
|
||||
static TemplateArgument getEmptyPack() {
|
||||
return TemplateArgument((TemplateArgument*)0, 0);
|
||||
}
|
||||
|
||||
/// \brief Create a new template argument pack by copying the given set of
|
||||
/// template arguments.
|
||||
static TemplateArgument CreatePackCopy(ASTContext &Context,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
|
||||
/// \brief Return the kind of stored template argument.
|
||||
ArgKind getKind() const { return (ArgKind)Kind; }
|
||||
|
||||
/// \brief Determine whether this template argument has no value.
|
||||
bool isNull() const { return Kind == Null; }
|
||||
|
||||
/// \brief Whether this template argument is dependent on a template
|
||||
/// parameter such that its result can change from one instantiation to
|
||||
/// another.
|
||||
bool isDependent() const;
|
||||
|
||||
/// \brief Whether this template argument is dependent on a template
|
||||
/// parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Whether this template argument contains an unexpanded
|
||||
/// parameter pack.
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
||||
/// \brief Determine whether this template argument is a pack expansion.
|
||||
bool isPackExpansion() const;
|
||||
|
||||
/// \brief Retrieve the type for a type template argument.
|
||||
QualType getAsType() const {
|
||||
assert(Kind == Type && "Unexpected kind");
|
||||
return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
|
||||
}
|
||||
|
||||
/// \brief Retrieve the declaration for a declaration non-type
|
||||
/// template argument.
|
||||
ValueDecl *getAsDecl() const {
|
||||
assert(Kind == Declaration && "Unexpected kind");
|
||||
return DeclArg.D;
|
||||
}
|
||||
|
||||
/// \brief Retrieve whether a declaration is binding to a
|
||||
/// reference parameter in a declaration non-type template argument.
|
||||
bool isDeclForReferenceParam() const {
|
||||
assert(Kind == Declaration && "Unexpected kind");
|
||||
return DeclArg.ForRefParam;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the type for null non-type template argument.
|
||||
QualType getNullPtrType() const {
|
||||
assert(Kind == NullPtr && "Unexpected kind");
|
||||
return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template name for a template name argument.
|
||||
TemplateName getAsTemplate() const {
|
||||
assert(Kind == Template && "Unexpected kind");
|
||||
return TemplateName::getFromVoidPointer(TemplateArg.Name);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template argument as a template name; if the argument
|
||||
/// is a pack expansion, return the pattern as a template name.
|
||||
TemplateName getAsTemplateOrTemplatePattern() const {
|
||||
assert((Kind == Template || Kind == TemplateExpansion) &&
|
||||
"Unexpected kind");
|
||||
|
||||
return TemplateName::getFromVoidPointer(TemplateArg.Name);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the number of expansions that a template template argument
|
||||
/// expansion will produce, if known.
|
||||
Optional<unsigned> getNumTemplateExpansions() const;
|
||||
|
||||
/// \brief Retrieve the template argument as an integral value.
|
||||
// FIXME: Provide a way to read the integral data without copying the value.
|
||||
llvm::APSInt getAsIntegral() const {
|
||||
assert(Kind == Integral && "Unexpected kind");
|
||||
using namespace llvm;
|
||||
if (Integer.BitWidth <= 64)
|
||||
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
|
||||
|
||||
unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
|
||||
return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
|
||||
Integer.IsUnsigned);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the type of the integral value.
|
||||
QualType getIntegralType() const {
|
||||
assert(Kind == Integral && "Unexpected kind");
|
||||
return QualType::getFromOpaquePtr(Integer.Type);
|
||||
}
|
||||
|
||||
void setIntegralType(QualType T) {
|
||||
assert(Kind == Integral && "Unexpected kind");
|
||||
Integer.Type = T.getAsOpaquePtr();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template argument as an expression.
|
||||
Expr *getAsExpr() const {
|
||||
assert(Kind == Expression && "Unexpected kind");
|
||||
return reinterpret_cast<Expr *>(TypeOrValue);
|
||||
}
|
||||
|
||||
/// \brief Iterator that traverses the elements of a template argument pack.
|
||||
typedef const TemplateArgument * pack_iterator;
|
||||
|
||||
/// \brief Iterator referencing the first argument of a template argument
|
||||
/// pack.
|
||||
pack_iterator pack_begin() const {
|
||||
assert(Kind == Pack);
|
||||
return Args.Args;
|
||||
}
|
||||
|
||||
/// \brief Iterator referencing one past the last argument of a template
|
||||
/// argument pack.
|
||||
pack_iterator pack_end() const {
|
||||
assert(Kind == Pack);
|
||||
return Args.Args + Args.NumArgs;
|
||||
}
|
||||
|
||||
/// \brief The number of template arguments in the given template argument
|
||||
/// pack.
|
||||
unsigned pack_size() const {
|
||||
assert(Kind == Pack);
|
||||
return Args.NumArgs;
|
||||
}
|
||||
|
||||
/// \brief Return the array of arguments in this template argument pack.
|
||||
llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
|
||||
assert(Kind == Pack);
|
||||
return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
|
||||
}
|
||||
|
||||
/// \brief Determines whether two template arguments are superficially the
|
||||
/// same.
|
||||
bool structurallyEquals(const TemplateArgument &Other) const;
|
||||
|
||||
/// \brief When the template argument is a pack expansion, returns
|
||||
/// the pattern of the pack expansion.
|
||||
TemplateArgument getPackExpansionPattern() const;
|
||||
|
||||
/// \brief Print this template argument to the given output stream.
|
||||
void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
|
||||
|
||||
/// \brief Used to insert TemplateArguments into FoldingSets.
|
||||
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
|
||||
};
|
||||
|
||||
/// Location information for a TemplateArgument.
|
||||
struct TemplateArgumentLocInfo {
|
||||
private:
|
||||
|
||||
struct T {
|
||||
// FIXME: We'd like to just use the qualifier in the TemplateName,
|
||||
// but template arguments get canonicalized too quickly.
|
||||
NestedNameSpecifier *Qualifier;
|
||||
void *QualifierLocData;
|
||||
unsigned TemplateNameLoc;
|
||||
unsigned EllipsisLoc;
|
||||
};
|
||||
|
||||
union {
|
||||
struct T Template;
|
||||
Expr *Expression;
|
||||
TypeSourceInfo *Declarator;
|
||||
};
|
||||
|
||||
public:
|
||||
TemplateArgumentLocInfo();
|
||||
|
||||
TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
|
||||
|
||||
TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
|
||||
|
||||
TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation EllipsisLoc)
|
||||
{
|
||||
Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
|
||||
Template.QualifierLocData = QualifierLoc.getOpaqueData();
|
||||
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
|
||||
Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
|
||||
}
|
||||
|
||||
TypeSourceInfo *getAsTypeSourceInfo() const {
|
||||
return Declarator;
|
||||
}
|
||||
|
||||
Expr *getAsExpr() const {
|
||||
return Expression;
|
||||
}
|
||||
|
||||
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
|
||||
return NestedNameSpecifierLoc(Template.Qualifier,
|
||||
Template.QualifierLocData);
|
||||
}
|
||||
|
||||
SourceLocation getTemplateNameLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
|
||||
}
|
||||
|
||||
SourceLocation getTemplateEllipsisLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
|
||||
}
|
||||
};
|
||||
|
||||
/// Location wrapper for a TemplateArgument. TemplateArgument is to
|
||||
/// TemplateArgumentLoc as Type is to TypeLoc.
|
||||
class TemplateArgumentLoc {
|
||||
TemplateArgument Argument;
|
||||
TemplateArgumentLocInfo LocInfo;
|
||||
|
||||
public:
|
||||
TemplateArgumentLoc() {}
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument,
|
||||
TemplateArgumentLocInfo Opaque)
|
||||
: Argument(Argument), LocInfo(Opaque) {
|
||||
}
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
|
||||
: Argument(Argument), LocInfo(TInfo) {
|
||||
assert(Argument.getKind() == TemplateArgument::Type);
|
||||
}
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
|
||||
: Argument(Argument), LocInfo(E) {
|
||||
assert(Argument.getKind() == TemplateArgument::Expression);
|
||||
}
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation EllipsisLoc = SourceLocation())
|
||||
: Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
|
||||
assert(Argument.getKind() == TemplateArgument::Template ||
|
||||
Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
}
|
||||
|
||||
/// \brief - Fetches the primary location of the argument.
|
||||
SourceLocation getLocation() const {
|
||||
if (Argument.getKind() == TemplateArgument::Template ||
|
||||
Argument.getKind() == TemplateArgument::TemplateExpansion)
|
||||
return getTemplateNameLoc();
|
||||
|
||||
return getSourceRange().getBegin();
|
||||
}
|
||||
|
||||
/// \brief - Fetches the full source range of the argument.
|
||||
SourceRange getSourceRange() const LLVM_READONLY;
|
||||
|
||||
const TemplateArgument &getArgument() const {
|
||||
return Argument;
|
||||
}
|
||||
|
||||
TemplateArgumentLocInfo getLocInfo() const {
|
||||
return LocInfo;
|
||||
}
|
||||
|
||||
TypeSourceInfo *getTypeSourceInfo() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Type);
|
||||
return LocInfo.getAsTypeSourceInfo();
|
||||
}
|
||||
|
||||
Expr *getSourceExpression() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Expression);
|
||||
return LocInfo.getAsExpr();
|
||||
}
|
||||
|
||||
Expr *getSourceDeclExpression() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Declaration);
|
||||
return LocInfo.getAsExpr();
|
||||
}
|
||||
|
||||
Expr *getSourceNullPtrExpression() const {
|
||||
assert(Argument.getKind() == TemplateArgument::NullPtr);
|
||||
return LocInfo.getAsExpr();
|
||||
}
|
||||
|
||||
Expr *getSourceIntegralExpression() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Integral);
|
||||
return LocInfo.getAsExpr();
|
||||
}
|
||||
|
||||
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Template ||
|
||||
Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
return LocInfo.getTemplateQualifierLoc();
|
||||
}
|
||||
|
||||
SourceLocation getTemplateNameLoc() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Template ||
|
||||
Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
return LocInfo.getTemplateNameLoc();
|
||||
}
|
||||
|
||||
SourceLocation getTemplateEllipsisLoc() const {
|
||||
assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
return LocInfo.getTemplateEllipsisLoc();
|
||||
}
|
||||
|
||||
/// \brief When the template argument is a pack expansion, returns
|
||||
/// the pattern of the pack expansion.
|
||||
///
|
||||
/// \param Ellipsis Will be set to the location of the ellipsis.
|
||||
///
|
||||
/// \param NumExpansions Will be set to the number of expansions that will
|
||||
/// be generated from this pack expansion, if known a priori.
|
||||
TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
|
||||
Optional<unsigned> &NumExpansions,
|
||||
ASTContext &Context) const;
|
||||
};
|
||||
|
||||
/// A convenient class for passing around template argument
|
||||
/// information. Designed to be passed by reference.
|
||||
class TemplateArgumentListInfo {
|
||||
SmallVector<TemplateArgumentLoc, 8> Arguments;
|
||||
SourceLocation LAngleLoc;
|
||||
SourceLocation RAngleLoc;
|
||||
|
||||
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
|
||||
// instead.
|
||||
void* operator new(size_t bytes, ASTContext& C);
|
||||
|
||||
public:
|
||||
TemplateArgumentListInfo() {}
|
||||
|
||||
TemplateArgumentListInfo(SourceLocation LAngleLoc,
|
||||
SourceLocation RAngleLoc)
|
||||
: LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
|
||||
|
||||
SourceLocation getLAngleLoc() const { return LAngleLoc; }
|
||||
SourceLocation getRAngleLoc() const { return RAngleLoc; }
|
||||
|
||||
void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
|
||||
void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
|
||||
|
||||
unsigned size() const { return Arguments.size(); }
|
||||
|
||||
const TemplateArgumentLoc *getArgumentArray() const {
|
||||
return Arguments.data();
|
||||
}
|
||||
|
||||
const TemplateArgumentLoc &operator[](unsigned I) const {
|
||||
return Arguments[I];
|
||||
}
|
||||
|
||||
void addArgument(const TemplateArgumentLoc &Loc) {
|
||||
Arguments.push_back(Loc);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents an explicit template argument list in C++, e.g.,
|
||||
/// the "<int>" in "sort<int>".
|
||||
/// This is safe to be used inside an AST node, in contrast with
|
||||
/// TemplateArgumentListInfo.
|
||||
struct ASTTemplateArgumentListInfo {
|
||||
/// \brief The source location of the left angle bracket ('<').
|
||||
SourceLocation LAngleLoc;
|
||||
|
||||
/// \brief The source location of the right angle bracket ('>').
|
||||
SourceLocation RAngleLoc;
|
||||
|
||||
union {
|
||||
/// \brief The number of template arguments in TemplateArgs.
|
||||
/// The actual template arguments (if any) are stored after the
|
||||
/// ExplicitTemplateArgumentList structure.
|
||||
unsigned NumTemplateArgs;
|
||||
|
||||
/// Force ASTTemplateArgumentListInfo to the right alignment
|
||||
/// for the following array of TemplateArgumentLocs.
|
||||
void *Aligner;
|
||||
};
|
||||
|
||||
/// \brief Retrieve the template arguments
|
||||
TemplateArgumentLoc *getTemplateArgs() {
|
||||
return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template arguments
|
||||
const TemplateArgumentLoc *getTemplateArgs() const {
|
||||
return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
|
||||
}
|
||||
|
||||
const TemplateArgumentLoc &operator[](unsigned I) const {
|
||||
return getTemplateArgs()[I];
|
||||
}
|
||||
|
||||
static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
|
||||
const TemplateArgumentListInfo &List);
|
||||
|
||||
void initializeFrom(const TemplateArgumentListInfo &List);
|
||||
void initializeFrom(const TemplateArgumentListInfo &List,
|
||||
bool &Dependent, bool &InstantiationDependent,
|
||||
bool &ContainsUnexpandedParameterPack);
|
||||
void copyInto(TemplateArgumentListInfo &List) const;
|
||||
static std::size_t sizeFor(unsigned NumTemplateArgs);
|
||||
};
|
||||
|
||||
/// \brief Extends ASTTemplateArgumentListInfo with the source location
|
||||
/// information for the template keyword; this is used as part of the
|
||||
/// representation of qualified identifiers, such as S<T>::template apply<T>.
|
||||
struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
|
||||
typedef ASTTemplateArgumentListInfo Base;
|
||||
|
||||
// NOTE: the source location of the (optional) template keyword is
|
||||
// stored after all template arguments.
|
||||
|
||||
/// \brief Get the source location of the template keyword.
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
return *reinterpret_cast<const SourceLocation*>
|
||||
(getTemplateArgs() + NumTemplateArgs);
|
||||
}
|
||||
|
||||
/// \brief Sets the source location of the template keyword.
|
||||
void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
|
||||
*reinterpret_cast<SourceLocation*>
|
||||
(getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
|
||||
}
|
||||
|
||||
static const ASTTemplateKWAndArgsInfo*
|
||||
Create(ASTContext &C, SourceLocation TemplateKWLoc,
|
||||
const TemplateArgumentListInfo &List);
|
||||
|
||||
void initializeFrom(SourceLocation TemplateKWLoc,
|
||||
const TemplateArgumentListInfo &List);
|
||||
void initializeFrom(SourceLocation TemplateKWLoc,
|
||||
const TemplateArgumentListInfo &List,
|
||||
bool &Dependent, bool &InstantiationDependent,
|
||||
bool &ContainsUnexpandedParameterPack);
|
||||
void initializeFrom(SourceLocation TemplateKWLoc);
|
||||
|
||||
static std::size_t sizeFor(unsigned NumTemplateArgs);
|
||||
};
|
||||
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const TemplateArgument &Arg);
|
||||
|
||||
inline TemplateSpecializationType::iterator
|
||||
TemplateSpecializationType::end() const {
|
||||
return getArgs() + getNumArgs();
|
||||
}
|
||||
|
||||
inline DependentTemplateSpecializationType::iterator
|
||||
DependentTemplateSpecializationType::end() const {
|
||||
return getArgs() + getNumArgs();
|
||||
}
|
||||
|
||||
inline const TemplateArgument &
|
||||
TemplateSpecializationType::getArg(unsigned Idx) const {
|
||||
assert(Idx < getNumArgs() && "Template argument out of range");
|
||||
return getArgs()[Idx];
|
||||
}
|
||||
|
||||
inline const TemplateArgument &
|
||||
DependentTemplateSpecializationType::getArg(unsigned Idx) const {
|
||||
assert(Idx < getNumArgs() && "Template argument out of range");
|
||||
return getArgs()[Idx];
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
562
thirdparty/clang/include/clang/AST/TemplateName.h
vendored
Normal file
562
thirdparty/clang/include/clang/AST/TemplateName.h
vendored
Normal file
@@ -0,0 +1,562 @@
|
||||
//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the TemplateName interface and subclasses.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
|
||||
#define LLVM_CLANG_AST_TEMPLATENAME_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class DependentTemplateName;
|
||||
class DiagnosticBuilder;
|
||||
class IdentifierInfo;
|
||||
class NestedNameSpecifier;
|
||||
class OverloadedTemplateStorage;
|
||||
struct PrintingPolicy;
|
||||
class QualifiedTemplateName;
|
||||
class NamedDecl;
|
||||
class SubstTemplateTemplateParmStorage;
|
||||
class SubstTemplateTemplateParmPackStorage;
|
||||
class TemplateArgument;
|
||||
class TemplateDecl;
|
||||
class TemplateTemplateParmDecl;
|
||||
|
||||
/// \brief Implementation class used to describe either a set of overloaded
|
||||
/// template names or an already-substituted template template parameter pack.
|
||||
class UncommonTemplateNameStorage {
|
||||
protected:
|
||||
enum Kind {
|
||||
Overloaded,
|
||||
SubstTemplateTemplateParm,
|
||||
SubstTemplateTemplateParmPack
|
||||
};
|
||||
|
||||
struct BitsTag {
|
||||
/// \brief A Kind.
|
||||
unsigned Kind : 2;
|
||||
|
||||
/// \brief The number of stored templates or template arguments,
|
||||
/// depending on which subclass we have.
|
||||
unsigned Size : 30;
|
||||
};
|
||||
|
||||
union {
|
||||
struct BitsTag Bits;
|
||||
void *PointerAlignment;
|
||||
};
|
||||
|
||||
UncommonTemplateNameStorage(Kind kind, unsigned size) {
|
||||
Bits.Kind = kind;
|
||||
Bits.Size = size;
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned size() const { return Bits.Size; }
|
||||
|
||||
OverloadedTemplateStorage *getAsOverloadedStorage() {
|
||||
return Bits.Kind == Overloaded
|
||||
? reinterpret_cast<OverloadedTemplateStorage *>(this)
|
||||
: 0;
|
||||
}
|
||||
|
||||
SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
|
||||
return Bits.Kind == SubstTemplateTemplateParm
|
||||
? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
|
||||
: 0;
|
||||
}
|
||||
|
||||
SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
|
||||
return Bits.Kind == SubstTemplateTemplateParmPack
|
||||
? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
|
||||
: 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A structure for storing the information associated with an
|
||||
/// overloaded template name.
|
||||
class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
|
||||
friend class ASTContext;
|
||||
|
||||
OverloadedTemplateStorage(unsigned size)
|
||||
: UncommonTemplateNameStorage(Overloaded, size) { }
|
||||
|
||||
NamedDecl **getStorage() {
|
||||
return reinterpret_cast<NamedDecl **>(this + 1);
|
||||
}
|
||||
NamedDecl * const *getStorage() const {
|
||||
return reinterpret_cast<NamedDecl *const *>(this + 1);
|
||||
}
|
||||
|
||||
public:
|
||||
typedef NamedDecl *const *iterator;
|
||||
|
||||
iterator begin() const { return getStorage(); }
|
||||
iterator end() const { return getStorage() + size(); }
|
||||
};
|
||||
|
||||
/// \brief A structure for storing an already-substituted template template
|
||||
/// parameter pack.
|
||||
///
|
||||
/// This kind of template names occurs when the parameter pack has been
|
||||
/// provided with a template template argument pack in a context where its
|
||||
/// enclosing pack expansion could not be fully expanded.
|
||||
class SubstTemplateTemplateParmPackStorage
|
||||
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode
|
||||
{
|
||||
TemplateTemplateParmDecl *Parameter;
|
||||
const TemplateArgument *Arguments;
|
||||
|
||||
public:
|
||||
SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
|
||||
unsigned Size,
|
||||
const TemplateArgument *Arguments)
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
|
||||
Parameter(Parameter), Arguments(Arguments) { }
|
||||
|
||||
/// \brief Retrieve the template template parameter pack being substituted.
|
||||
TemplateTemplateParmDecl *getParameterPack() const {
|
||||
return Parameter;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template template argument pack with which this
|
||||
/// parameter was substituted.
|
||||
TemplateArgument getArgumentPack() const;
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
ASTContext &Context,
|
||||
TemplateTemplateParmDecl *Parameter,
|
||||
const TemplateArgument &ArgPack);
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ template name within the type system.
|
||||
///
|
||||
/// A C++ template name refers to a template within the C++ type
|
||||
/// system. In most cases, a template name is simply a reference to a
|
||||
/// class template, e.g.
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T> class X { };
|
||||
///
|
||||
/// X<int> xi;
|
||||
/// \endcode
|
||||
///
|
||||
/// Here, the 'X' in \c X<int> is a template name that refers to the
|
||||
/// declaration of the class template X, above. Template names can
|
||||
/// also refer to function templates, C++0x template aliases, etc.
|
||||
///
|
||||
/// Some template names are dependent. For example, consider:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
|
||||
/// typedef typename MetaFun::template apply<T1, T2>::type type;
|
||||
/// };
|
||||
/// \endcode
|
||||
///
|
||||
/// Here, "apply" is treated as a template name within the typename
|
||||
/// specifier in the typedef. "apply" is a nested template, and can
|
||||
/// only be understood in the context of
|
||||
class TemplateName {
|
||||
typedef llvm::PointerUnion4<TemplateDecl *,
|
||||
UncommonTemplateNameStorage *,
|
||||
QualifiedTemplateName *,
|
||||
DependentTemplateName *> StorageType;
|
||||
|
||||
StorageType Storage;
|
||||
|
||||
explicit TemplateName(void *Ptr) {
|
||||
Storage = StorageType::getFromOpaqueValue(Ptr);
|
||||
}
|
||||
|
||||
public:
|
||||
// \brief Kind of name that is actually stored.
|
||||
enum NameKind {
|
||||
/// \brief A single template declaration.
|
||||
Template,
|
||||
/// \brief A set of overloaded template declarations.
|
||||
OverloadedTemplate,
|
||||
/// \brief A qualified template name, where the qualification is kept
|
||||
/// to describe the source code as written.
|
||||
QualifiedTemplate,
|
||||
/// \brief A dependent template name that has not been resolved to a
|
||||
/// template (or set of templates).
|
||||
DependentTemplate,
|
||||
/// \brief A template template parameter that has been substituted
|
||||
/// for some other template name.
|
||||
SubstTemplateTemplateParm,
|
||||
/// \brief A template template parameter pack that has been substituted for
|
||||
/// a template template argument pack, but has not yet been expanded into
|
||||
/// individual arguments.
|
||||
SubstTemplateTemplateParmPack
|
||||
};
|
||||
|
||||
TemplateName() : Storage() { }
|
||||
explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
|
||||
explicit TemplateName(OverloadedTemplateStorage *Storage)
|
||||
: Storage(Storage) { }
|
||||
explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
|
||||
explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
|
||||
: Storage(Storage) { }
|
||||
explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
|
||||
explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
|
||||
|
||||
/// \brief Determine whether this template name is NULL.
|
||||
bool isNull() const { return Storage.isNull(); }
|
||||
|
||||
// \brief Get the kind of name that is actually stored.
|
||||
NameKind getKind() const;
|
||||
|
||||
/// \brief Retrieve the underlying template declaration that
|
||||
/// this template name refers to, if known.
|
||||
///
|
||||
/// \returns The template declaration that this template name refers
|
||||
/// to, if any. If the template name does not refer to a specific
|
||||
/// declaration because it is a dependent name, or if it refers to a
|
||||
/// set of function templates, returns NULL.
|
||||
TemplateDecl *getAsTemplateDecl() const;
|
||||
|
||||
/// \brief Retrieve the underlying, overloaded function template
|
||||
// declarations that this template name refers to, if known.
|
||||
///
|
||||
/// \returns The set of overloaded function templates that this template
|
||||
/// name refers to, if known. If the template name does not refer to a
|
||||
/// specific set of function templates because it is a dependent name or
|
||||
/// refers to a single template, returns NULL.
|
||||
OverloadedTemplateStorage *getAsOverloadedTemplate() const {
|
||||
if (UncommonTemplateNameStorage *Uncommon =
|
||||
Storage.dyn_cast<UncommonTemplateNameStorage *>())
|
||||
return Uncommon->getAsOverloadedStorage();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the substituted template template parameter, if
|
||||
/// known.
|
||||
///
|
||||
/// \returns The storage for the substituted template template parameter,
|
||||
/// if known. Otherwise, returns NULL.
|
||||
SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const {
|
||||
if (UncommonTemplateNameStorage *uncommon =
|
||||
Storage.dyn_cast<UncommonTemplateNameStorage *>())
|
||||
return uncommon->getAsSubstTemplateTemplateParm();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the substituted template template parameter pack, if
|
||||
/// known.
|
||||
///
|
||||
/// \returns The storage for the substituted template template parameter pack,
|
||||
/// if known. Otherwise, returns NULL.
|
||||
SubstTemplateTemplateParmPackStorage *
|
||||
getAsSubstTemplateTemplateParmPack() const {
|
||||
if (UncommonTemplateNameStorage *Uncommon =
|
||||
Storage.dyn_cast<UncommonTemplateNameStorage *>())
|
||||
return Uncommon->getAsSubstTemplateTemplateParmPack();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the underlying qualified template name
|
||||
/// structure, if any.
|
||||
QualifiedTemplateName *getAsQualifiedTemplateName() const {
|
||||
return Storage.dyn_cast<QualifiedTemplateName *>();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the underlying dependent template name
|
||||
/// structure, if any.
|
||||
DependentTemplateName *getAsDependentTemplateName() const {
|
||||
return Storage.dyn_cast<DependentTemplateName *>();
|
||||
}
|
||||
|
||||
TemplateName getUnderlying() const;
|
||||
|
||||
/// \brief Determines whether this is a dependent template name.
|
||||
bool isDependent() const;
|
||||
|
||||
/// \brief Determines whether this is a template name that somehow
|
||||
/// depends on a template parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Determines whether this template name contains an
|
||||
/// unexpanded parameter pack (for C++0x variadic templates).
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
||||
/// \brief Print the template name.
|
||||
///
|
||||
/// \param OS the output stream to which the template name will be
|
||||
/// printed.
|
||||
///
|
||||
/// \param SuppressNNS if true, don't print the
|
||||
/// nested-name-specifier that precedes the template name (if it has
|
||||
/// one).
|
||||
void print(raw_ostream &OS, const PrintingPolicy &Policy,
|
||||
bool SuppressNNS = false) const;
|
||||
|
||||
/// \brief Debugging aid that dumps the template name.
|
||||
void dump(raw_ostream &OS) const;
|
||||
|
||||
/// \brief Debugging aid that dumps the template name to standard
|
||||
/// error.
|
||||
void dump() const;
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
ID.AddPointer(Storage.getOpaqueValue());
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template name as a void pointer.
|
||||
void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
|
||||
|
||||
/// \brief Build a template name from a void pointer.
|
||||
static TemplateName getFromVoidPointer(void *Ptr) {
|
||||
return TemplateName(Ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending TemplateName's
|
||||
/// into a diagnostic with <<.
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
TemplateName N);
|
||||
|
||||
/// \brief A structure for storing the information associated with a
|
||||
/// substituted template template parameter.
|
||||
class SubstTemplateTemplateParmStorage
|
||||
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
|
||||
TemplateTemplateParmDecl *Parameter;
|
||||
TemplateName Replacement;
|
||||
|
||||
SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
|
||||
TemplateName replacement)
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
|
||||
Parameter(parameter), Replacement(replacement) {}
|
||||
|
||||
public:
|
||||
TemplateTemplateParmDecl *getParameter() const { return Parameter; }
|
||||
TemplateName getReplacement() const { return Replacement; }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID);
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
TemplateTemplateParmDecl *parameter,
|
||||
TemplateName replacement);
|
||||
};
|
||||
|
||||
inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
|
||||
: Storage(Storage) { }
|
||||
|
||||
inline TemplateName TemplateName::getUnderlying() const {
|
||||
if (SubstTemplateTemplateParmStorage *subst
|
||||
= getAsSubstTemplateTemplateParm())
|
||||
return subst->getReplacement().getUnderlying();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Represents a template name that was expressed as a
|
||||
/// qualified name.
|
||||
///
|
||||
/// This kind of template name refers to a template name that was
|
||||
/// preceded by a nested name specifier, e.g., \c std::vector. Here,
|
||||
/// the nested name specifier is "std::" and the template name is the
|
||||
/// declaration for "vector". The QualifiedTemplateName class is only
|
||||
/// used to provide "sugar" for template names that were expressed
|
||||
/// with a qualified name, and has no semantic meaning. In this
|
||||
/// manner, it is to TemplateName what ElaboratedType is to Type,
|
||||
/// providing extra syntactic sugar for downstream clients.
|
||||
class QualifiedTemplateName : public llvm::FoldingSetNode {
|
||||
/// \brief The nested name specifier that qualifies the template name.
|
||||
///
|
||||
/// The bit is used to indicate whether the "template" keyword was
|
||||
/// present before the template name itself. Note that the
|
||||
/// "template" keyword is always redundant in this case (otherwise,
|
||||
/// the template name would be a dependent name and we would express
|
||||
/// this name with DependentTemplateName).
|
||||
llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
|
||||
|
||||
/// \brief The template declaration or set of overloaded function templates
|
||||
/// that this qualified name refers to.
|
||||
TemplateDecl *Template;
|
||||
|
||||
friend class ASTContext;
|
||||
|
||||
QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
|
||||
TemplateDecl *Template)
|
||||
: Qualifier(NNS, TemplateKeyword? 1 : 0),
|
||||
Template(Template) { }
|
||||
|
||||
public:
|
||||
/// \brief Return the nested name specifier that qualifies this name.
|
||||
NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
|
||||
|
||||
/// \brief Whether the template name was prefixed by the "template"
|
||||
/// keyword.
|
||||
bool hasTemplateKeyword() const { return Qualifier.getInt(); }
|
||||
|
||||
/// \brief The template declaration that this qualified name refers
|
||||
/// to.
|
||||
TemplateDecl *getDecl() const { return Template; }
|
||||
|
||||
/// \brief The template declaration to which this qualified name
|
||||
/// refers.
|
||||
TemplateDecl *getTemplateDecl() const { return Template; }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
|
||||
bool TemplateKeyword, TemplateDecl *Template) {
|
||||
ID.AddPointer(NNS);
|
||||
ID.AddBoolean(TemplateKeyword);
|
||||
ID.AddPointer(Template);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a dependent template name that cannot be
|
||||
/// resolved prior to template instantiation.
|
||||
///
|
||||
/// This kind of template name refers to a dependent template name,
|
||||
/// including its nested name specifier (if any). For example,
|
||||
/// DependentTemplateName can refer to "MetaFun::template apply",
|
||||
/// where "MetaFun::" is the nested name specifier and "apply" is the
|
||||
/// template name referenced. The "template" keyword is implied.
|
||||
class DependentTemplateName : public llvm::FoldingSetNode {
|
||||
/// \brief The nested name specifier that qualifies the template
|
||||
/// name.
|
||||
///
|
||||
/// The bit stored in this qualifier describes whether the \c Name field
|
||||
/// is interpreted as an IdentifierInfo pointer (when clear) or as an
|
||||
/// overloaded operator kind (when set).
|
||||
llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
|
||||
|
||||
/// \brief The dependent template name.
|
||||
union {
|
||||
/// \brief The identifier template name.
|
||||
///
|
||||
/// Only valid when the bit on \c Qualifier is clear.
|
||||
const IdentifierInfo *Identifier;
|
||||
|
||||
/// \brief The overloaded operator name.
|
||||
///
|
||||
/// Only valid when the bit on \c Qualifier is set.
|
||||
OverloadedOperatorKind Operator;
|
||||
};
|
||||
|
||||
/// \brief The canonical template name to which this dependent
|
||||
/// template name refers.
|
||||
///
|
||||
/// The canonical template name for a dependent template name is
|
||||
/// another dependent template name whose nested name specifier is
|
||||
/// canonical.
|
||||
TemplateName CanonicalTemplateName;
|
||||
|
||||
friend class ASTContext;
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
const IdentifierInfo *Identifier)
|
||||
: Qualifier(Qualifier, false), Identifier(Identifier),
|
||||
CanonicalTemplateName(this) { }
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
const IdentifierInfo *Identifier,
|
||||
TemplateName Canon)
|
||||
: Qualifier(Qualifier, false), Identifier(Identifier),
|
||||
CanonicalTemplateName(Canon) { }
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
OverloadedOperatorKind Operator)
|
||||
: Qualifier(Qualifier, true), Operator(Operator),
|
||||
CanonicalTemplateName(this) { }
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
OverloadedOperatorKind Operator,
|
||||
TemplateName Canon)
|
||||
: Qualifier(Qualifier, true), Operator(Operator),
|
||||
CanonicalTemplateName(Canon) { }
|
||||
|
||||
public:
|
||||
/// \brief Return the nested name specifier that qualifies this name.
|
||||
NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
|
||||
|
||||
/// \brief Determine whether this template name refers to an identifier.
|
||||
bool isIdentifier() const { return !Qualifier.getInt(); }
|
||||
|
||||
/// \brief Returns the identifier to which this template name refers.
|
||||
const IdentifierInfo *getIdentifier() const {
|
||||
assert(isIdentifier() && "Template name isn't an identifier?");
|
||||
return Identifier;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this template name refers to an overloaded
|
||||
/// operator.
|
||||
bool isOverloadedOperator() const { return Qualifier.getInt(); }
|
||||
|
||||
/// \brief Return the overloaded operator to which this template name refers.
|
||||
OverloadedOperatorKind getOperator() const {
|
||||
assert(isOverloadedOperator() &&
|
||||
"Template name isn't an overloaded operator?");
|
||||
return Operator;
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
if (isIdentifier())
|
||||
Profile(ID, getQualifier(), getIdentifier());
|
||||
else
|
||||
Profile(ID, getQualifier(), getOperator());
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo *Identifier) {
|
||||
ID.AddPointer(NNS);
|
||||
ID.AddBoolean(false);
|
||||
ID.AddPointer(Identifier);
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
|
||||
OverloadedOperatorKind Operator) {
|
||||
ID.AddPointer(NNS);
|
||||
ID.AddBoolean(true);
|
||||
ID.AddInteger(Operator);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang.
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// \brief The clang::TemplateName class is effectively a pointer.
|
||||
template<>
|
||||
class PointerLikeTypeTraits<clang::TemplateName> {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(clang::TemplateName TN) {
|
||||
return TN.getAsVoidPointer();
|
||||
}
|
||||
|
||||
static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
|
||||
return clang::TemplateName::getFromVoidPointer(Ptr);
|
||||
}
|
||||
|
||||
// No bits are available!
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
|
||||
} // end namespace llvm.
|
||||
|
||||
#endif
|
||||
5126
thirdparty/clang/include/clang/AST/Type.h
vendored
Normal file
5126
thirdparty/clang/include/clang/AST/Type.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1862
thirdparty/clang/include/clang/AST/TypeLoc.h
vendored
Normal file
1862
thirdparty/clang/include/clang/AST/TypeLoc.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
41
thirdparty/clang/include/clang/AST/TypeLocNodes.def
vendored
Normal file
41
thirdparty/clang/include/clang/AST/TypeLocNodes.def
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
//===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the TypeLoc info database. Each node is
|
||||
// enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc")
|
||||
// and base class (e.g., "DeclaratorLoc"). All nodes except QualifiedTypeLoc
|
||||
// are associated
|
||||
//
|
||||
// TYPELOC(Class, Base) - A TypeLoc subclass. If UNQUAL_TYPELOC is
|
||||
// provided, there will be exactly one of these, Qualified.
|
||||
//
|
||||
// UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
|
||||
//
|
||||
// ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef UNQUAL_TYPELOC
|
||||
# define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base)
|
||||
#endif
|
||||
|
||||
#ifndef ABSTRACT_TYPELOC
|
||||
# define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base)
|
||||
#endif
|
||||
|
||||
TYPELOC(Qualified, TypeLoc)
|
||||
#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc)
|
||||
#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc)
|
||||
#include "clang/AST/TypeNodes.def"
|
||||
|
||||
#undef DECLARATOR_TYPELOC
|
||||
#undef TYPESPEC_TYPELOC
|
||||
#undef ABSTRACT_TYPELOC
|
||||
#undef UNQUAL_TYPELOC
|
||||
#undef TYPELOC
|
||||
62
thirdparty/clang/include/clang/AST/TypeLocVisitor.h
vendored
Normal file
62
thirdparty/clang/include/clang/AST/TypeLocVisitor.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
//===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the TypeLocVisitor interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_TYPELOCVISITOR_H
|
||||
#define LLVM_CLANG_AST_TYPELOCVISITOR_H
|
||||
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/AST/TypeVisitor.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
#define DISPATCH(CLASSNAME) \
|
||||
return static_cast<ImplClass*>(this)-> \
|
||||
Visit##CLASSNAME(TyLoc.castAs<CLASSNAME>())
|
||||
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class TypeLocVisitor {
|
||||
public:
|
||||
RetTy Visit(TypeLoc TyLoc) {
|
||||
switch (TyLoc.getTypeLocClass()) {
|
||||
#define ABSTRACT_TYPELOC(CLASS, PARENT)
|
||||
#define TYPELOC(CLASS, PARENT) \
|
||||
case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
|
||||
#include "clang/AST/TypeLocNodes.def"
|
||||
}
|
||||
llvm_unreachable("unexpected type loc class!");
|
||||
}
|
||||
|
||||
RetTy Visit(UnqualTypeLoc TyLoc) {
|
||||
switch (TyLoc.getTypeLocClass()) {
|
||||
#define ABSTRACT_TYPELOC(CLASS, PARENT)
|
||||
#define TYPELOC(CLASS, PARENT) \
|
||||
case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
|
||||
#include "clang/AST/TypeLocNodes.def"
|
||||
}
|
||||
llvm_unreachable("unexpected type loc class!");
|
||||
}
|
||||
|
||||
#define TYPELOC(CLASS, PARENT) \
|
||||
RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
|
||||
DISPATCH(PARENT); \
|
||||
}
|
||||
#include "clang/AST/TypeLocNodes.def"
|
||||
|
||||
RetTy VisitTypeLoc(TypeLoc TyLoc) { return RetTy(); }
|
||||
};
|
||||
|
||||
#undef DISPATCH
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_TYPELOCVISITOR_H
|
||||
127
thirdparty/clang/include/clang/AST/TypeNodes.def
vendored
Normal file
127
thirdparty/clang/include/clang/AST/TypeNodes.def
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the AST type info database. Each type node is
|
||||
// enumerated by providing its name (e.g., "Builtin" or "Enum") and
|
||||
// base class (e.g., "Type" or "TagType"). Depending on where in the
|
||||
// abstract syntax tree the type will show up, the enumeration uses
|
||||
// one of four different macros:
|
||||
//
|
||||
// TYPE(Class, Base) - A type that can show up anywhere in the AST,
|
||||
// and might be dependent, canonical, or non-canonical. All clients
|
||||
// will need to understand these types.
|
||||
//
|
||||
// ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
|
||||
// the type hierarchy but has no concrete instances.
|
||||
//
|
||||
// NON_CANONICAL_TYPE(Class, Base) - A type that can show up
|
||||
// anywhere in the AST but will never be a part of a canonical
|
||||
// type. Clients that only need to deal with canonical types
|
||||
// (ignoring, e.g., typedefs and other type alises used for
|
||||
// pretty-printing) can ignore these types.
|
||||
//
|
||||
// DEPENDENT_TYPE(Class, Base) - A type that will only show up
|
||||
// within a C++ template that has not been instantiated, e.g., a
|
||||
// type that is always dependent. Clients that do not need to deal
|
||||
// with uninstantiated C++ templates can ignore these types.
|
||||
//
|
||||
// NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
|
||||
// is non-canonical unless it is dependent. Defaults to TYPE because
|
||||
// it is neither reliably dependent nor reliably non-canonical.
|
||||
//
|
||||
// There is a sixth macro, independent of the others. Most clients
|
||||
// will not need to use it.
|
||||
//
|
||||
// LEAF_TYPE(Class) - A type that never has inner types. Clients
|
||||
// which can operate on such types more efficiently may wish to do so.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ABSTRACT_TYPE
|
||||
# define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)
|
||||
#endif
|
||||
|
||||
#ifndef NON_CANONICAL_TYPE
|
||||
# define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)
|
||||
#endif
|
||||
|
||||
#ifndef DEPENDENT_TYPE
|
||||
# define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
|
||||
#endif
|
||||
|
||||
#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
|
||||
# define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
|
||||
#endif
|
||||
|
||||
TYPE(Builtin, Type)
|
||||
TYPE(Complex, Type)
|
||||
TYPE(Pointer, Type)
|
||||
TYPE(BlockPointer, Type)
|
||||
ABSTRACT_TYPE(Reference, Type)
|
||||
TYPE(LValueReference, ReferenceType)
|
||||
TYPE(RValueReference, ReferenceType)
|
||||
TYPE(MemberPointer, Type)
|
||||
ABSTRACT_TYPE(Array, Type)
|
||||
TYPE(ConstantArray, ArrayType)
|
||||
TYPE(IncompleteArray, ArrayType)
|
||||
TYPE(VariableArray, ArrayType)
|
||||
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
|
||||
DEPENDENT_TYPE(DependentSizedExtVector, Type)
|
||||
TYPE(Vector, Type)
|
||||
TYPE(ExtVector, VectorType)
|
||||
ABSTRACT_TYPE(Function, Type)
|
||||
TYPE(FunctionProto, FunctionType)
|
||||
TYPE(FunctionNoProto, FunctionType)
|
||||
DEPENDENT_TYPE(UnresolvedUsing, Type)
|
||||
NON_CANONICAL_TYPE(Paren, Type)
|
||||
NON_CANONICAL_TYPE(Typedef, Type)
|
||||
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
|
||||
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
|
||||
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
|
||||
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type)
|
||||
ABSTRACT_TYPE(Tag, Type)
|
||||
TYPE(Record, TagType)
|
||||
TYPE(Enum, TagType)
|
||||
NON_CANONICAL_TYPE(Elaborated, Type)
|
||||
NON_CANONICAL_TYPE(Attributed, Type)
|
||||
DEPENDENT_TYPE(TemplateTypeParm, Type)
|
||||
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
|
||||
DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
|
||||
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
|
||||
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Auto, Type)
|
||||
DEPENDENT_TYPE(InjectedClassName, Type)
|
||||
DEPENDENT_TYPE(DependentName, Type)
|
||||
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
|
||||
DEPENDENT_TYPE(PackExpansion, Type)
|
||||
TYPE(ObjCObject, Type)
|
||||
TYPE(ObjCInterface, ObjCObjectType)
|
||||
TYPE(ObjCObjectPointer, Type)
|
||||
TYPE(Atomic, Type)
|
||||
|
||||
#ifdef LAST_TYPE
|
||||
LAST_TYPE(Atomic)
|
||||
#undef LAST_TYPE
|
||||
#endif
|
||||
|
||||
// These types are always leaves in the type hierarchy.
|
||||
#ifdef LEAF_TYPE
|
||||
LEAF_TYPE(Enum)
|
||||
LEAF_TYPE(Builtin)
|
||||
LEAF_TYPE(Record)
|
||||
LEAF_TYPE(InjectedClassName)
|
||||
LEAF_TYPE(ObjCInterface)
|
||||
LEAF_TYPE(TemplateTypeParm)
|
||||
#undef LEAF_TYPE
|
||||
#endif
|
||||
|
||||
#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
|
||||
#undef DEPENDENT_TYPE
|
||||
#undef NON_CANONICAL_TYPE
|
||||
#undef ABSTRACT_TYPE
|
||||
#undef TYPE
|
||||
77
thirdparty/clang/include/clang/AST/TypeOrdering.h
vendored
Normal file
77
thirdparty/clang/include/clang/AST/TypeOrdering.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
//===-------------- TypeOrdering.h - Total ordering for types -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides a function objects and specializations that
|
||||
// allow QualType values to be sorted, used in std::maps, std::sets,
|
||||
// llvm::DenseMaps, and llvm::DenseSets.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_TYPE_ORDERING_H
|
||||
#define LLVM_CLANG_TYPE_ORDERING_H
|
||||
|
||||
#include "clang/AST/CanonicalType.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include <functional>
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// QualTypeOrdering - Function object that provides a total ordering
|
||||
/// on QualType values.
|
||||
struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> {
|
||||
bool operator()(QualType T1, QualType T2) const {
|
||||
return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
template<class> struct DenseMapInfo;
|
||||
|
||||
template<> struct DenseMapInfo<clang::QualType> {
|
||||
static inline clang::QualType getEmptyKey() { return clang::QualType(); }
|
||||
|
||||
static inline clang::QualType getTombstoneKey() {
|
||||
using clang::QualType;
|
||||
return QualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
|
||||
}
|
||||
|
||||
static unsigned getHashValue(clang::QualType Val) {
|
||||
return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
|
||||
((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
|
||||
}
|
||||
|
||||
static bool isEqual(clang::QualType LHS, clang::QualType RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct DenseMapInfo<clang::CanQualType> {
|
||||
static inline clang::CanQualType getEmptyKey() {
|
||||
return clang::CanQualType();
|
||||
}
|
||||
|
||||
static inline clang::CanQualType getTombstoneKey() {
|
||||
using clang::CanQualType;
|
||||
return CanQualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
|
||||
}
|
||||
|
||||
static unsigned getHashValue(clang::CanQualType Val) {
|
||||
return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
|
||||
((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
|
||||
}
|
||||
|
||||
static bool isEqual(clang::CanQualType LHS, clang::CanQualType RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
53
thirdparty/clang/include/clang/AST/TypeVisitor.h
vendored
Normal file
53
thirdparty/clang/include/clang/AST/TypeVisitor.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the TypeVisitor interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_TYPEVISITOR_H
|
||||
#define LLVM_CLANG_AST_TYPEVISITOR_H
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
#define DISPATCH(CLASS) \
|
||||
return static_cast<ImplClass*>(this)-> \
|
||||
Visit##CLASS(static_cast<const CLASS*>(T))
|
||||
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class TypeVisitor {
|
||||
public:
|
||||
RetTy Visit(const Type *T) {
|
||||
// Top switch stmt: dispatch to VisitFooType for each FooType.
|
||||
switch (T->getTypeClass()) {
|
||||
#define ABSTRACT_TYPE(CLASS, PARENT)
|
||||
#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
|
||||
#include "clang/AST/TypeNodes.def"
|
||||
}
|
||||
llvm_unreachable("Unknown type class!");
|
||||
}
|
||||
|
||||
// If the implementation chooses not to implement a certain visit method, fall
|
||||
// back on superclass.
|
||||
#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \
|
||||
DISPATCH(PARENT); \
|
||||
}
|
||||
#include "clang/AST/TypeNodes.def"
|
||||
|
||||
// Base case, ignore it. :)
|
||||
RetTy VisitType(const Type*) { return RetTy(); }
|
||||
};
|
||||
|
||||
#undef DISPATCH
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
189
thirdparty/clang/include/clang/AST/UnresolvedSet.h
vendored
Normal file
189
thirdparty/clang/include/clang/AST/UnresolvedSet.h
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the UnresolvedSet class, which is used to store
|
||||
// collections of declarations in the AST.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
|
||||
#define LLVM_CLANG_AST_UNRESOLVEDSET_H
|
||||
|
||||
#include "clang/AST/DeclAccessPair.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// The iterator over UnresolvedSets. Serves as both the const and
|
||||
/// non-const iterator.
|
||||
class UnresolvedSetIterator {
|
||||
private:
|
||||
typedef llvm::MutableArrayRef<DeclAccessPair> DeclsTy;
|
||||
typedef DeclsTy::iterator IteratorTy;
|
||||
|
||||
IteratorTy ir;
|
||||
|
||||
friend class UnresolvedSetImpl;
|
||||
friend class ASTUnresolvedSet;
|
||||
friend class OverloadExpr;
|
||||
explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
|
||||
explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
|
||||
ir(const_cast<DeclsTy::iterator>(ir)) {}
|
||||
|
||||
IteratorTy getIterator() const { return ir; }
|
||||
|
||||
public:
|
||||
UnresolvedSetIterator() {}
|
||||
|
||||
typedef std::iterator_traits<IteratorTy>::difference_type difference_type;
|
||||
typedef NamedDecl *value_type;
|
||||
typedef NamedDecl **pointer;
|
||||
typedef NamedDecl *reference;
|
||||
typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
|
||||
|
||||
NamedDecl *getDecl() const { return ir->getDecl(); }
|
||||
AccessSpecifier getAccess() const { return ir->getAccess(); }
|
||||
void setAccess(AccessSpecifier AS) { ir->setAccess(AS); }
|
||||
DeclAccessPair getPair() const { return *ir; }
|
||||
|
||||
NamedDecl *operator*() const { return getDecl(); }
|
||||
|
||||
UnresolvedSetIterator &operator++() { ++ir; return *this; }
|
||||
UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
|
||||
UnresolvedSetIterator &operator--() { --ir; return *this; }
|
||||
UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
|
||||
|
||||
UnresolvedSetIterator &operator+=(difference_type d) {
|
||||
ir += d; return *this;
|
||||
}
|
||||
UnresolvedSetIterator operator+(difference_type d) const {
|
||||
return UnresolvedSetIterator(ir + d);
|
||||
}
|
||||
UnresolvedSetIterator &operator-=(difference_type d) {
|
||||
ir -= d; return *this;
|
||||
}
|
||||
UnresolvedSetIterator operator-(difference_type d) const {
|
||||
return UnresolvedSetIterator(ir - d);
|
||||
}
|
||||
value_type operator[](difference_type d) const { return *(*this + d); }
|
||||
|
||||
difference_type operator-(const UnresolvedSetIterator &o) const {
|
||||
return ir - o.ir;
|
||||
}
|
||||
|
||||
bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; }
|
||||
bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; }
|
||||
bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; }
|
||||
bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; }
|
||||
bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
|
||||
bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
|
||||
};
|
||||
|
||||
/// UnresolvedSet - A set of unresolved declarations.
|
||||
class UnresolvedSetImpl {
|
||||
typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
|
||||
|
||||
// Don't allow direct construction, and only permit subclassing by
|
||||
// UnresolvedSet.
|
||||
private:
|
||||
template <unsigned N> friend class UnresolvedSet;
|
||||
UnresolvedSetImpl() {}
|
||||
UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
public:
|
||||
// We don't currently support assignment through this iterator, so we might
|
||||
// as well use the same implementation twice.
|
||||
typedef UnresolvedSetIterator iterator;
|
||||
typedef UnresolvedSetIterator const_iterator;
|
||||
|
||||
iterator begin() { return iterator(decls().begin()); }
|
||||
iterator end() { return iterator(decls().end()); }
|
||||
|
||||
const_iterator begin() const { return const_iterator(decls().begin()); }
|
||||
const_iterator end() const { return const_iterator(decls().end()); }
|
||||
|
||||
void addDecl(NamedDecl *D) {
|
||||
addDecl(D, AS_none);
|
||||
}
|
||||
|
||||
void addDecl(NamedDecl *D, AccessSpecifier AS) {
|
||||
decls().push_back(DeclAccessPair::make(D, AS));
|
||||
}
|
||||
|
||||
/// Replaces the given declaration with the new one, once.
|
||||
///
|
||||
/// \return true if the set changed
|
||||
bool replace(const NamedDecl* Old, NamedDecl *New) {
|
||||
for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
|
||||
if (I->getDecl() == Old)
|
||||
return (I->setDecl(New), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Replaces the declaration at the given iterator with the new one,
|
||||
/// preserving the original access bits.
|
||||
void replace(iterator I, NamedDecl *New) {
|
||||
I.ir->setDecl(New);
|
||||
}
|
||||
|
||||
void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
|
||||
I.ir->set(New, AS);
|
||||
}
|
||||
|
||||
void erase(unsigned I) {
|
||||
decls()[I] = decls().back();
|
||||
decls().pop_back();
|
||||
}
|
||||
|
||||
void erase(iterator I) {
|
||||
*I.ir = decls().back();
|
||||
decls().pop_back();
|
||||
}
|
||||
|
||||
void setAccess(iterator I, AccessSpecifier AS) {
|
||||
I.ir->setAccess(AS);
|
||||
}
|
||||
|
||||
void clear() { decls().clear(); }
|
||||
void set_size(unsigned N) { decls().set_size(N); }
|
||||
|
||||
bool empty() const { return decls().empty(); }
|
||||
unsigned size() const { return decls().size(); }
|
||||
|
||||
void append(iterator I, iterator E) {
|
||||
decls().append(I.ir, E.ir);
|
||||
}
|
||||
|
||||
DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
|
||||
const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
|
||||
|
||||
private:
|
||||
// These work because the only permitted subclass is UnresolvedSetImpl
|
||||
|
||||
DeclsTy &decls() {
|
||||
return *reinterpret_cast<DeclsTy*>(this);
|
||||
}
|
||||
const DeclsTy &decls() const {
|
||||
return *reinterpret_cast<const DeclsTy*>(this);
|
||||
}
|
||||
};
|
||||
|
||||
/// A set of unresolved declarations
|
||||
template <unsigned InlineCapacity> class UnresolvedSet :
|
||||
public UnresolvedSetImpl {
|
||||
SmallVector<DeclAccessPair, InlineCapacity> Decls;
|
||||
};
|
||||
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
167
thirdparty/clang/include/clang/AST/VTTBuilder.h
vendored
Normal file
167
thirdparty/clang/include/clang/AST/VTTBuilder.h
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This contains code dealing with generation of the layout of virtual table
|
||||
// tables (VTT).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_VTTBUILDER_H
|
||||
#define LLVM_CLANG_AST_VTTBUILDER_H
|
||||
|
||||
#include "clang/AST/BaseSubobject.h"
|
||||
#include "clang/AST/CXXInheritance.h"
|
||||
#include "clang/AST/GlobalDecl.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class VTTVTable {
|
||||
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
|
||||
CharUnits BaseOffset;
|
||||
|
||||
public:
|
||||
VTTVTable() {}
|
||||
VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
|
||||
: BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
|
||||
VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
|
||||
: BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
|
||||
BaseOffset(Base.getBaseOffset()) {}
|
||||
|
||||
const CXXRecordDecl *getBase() const {
|
||||
return BaseAndIsVirtual.getPointer();
|
||||
}
|
||||
|
||||
CharUnits getBaseOffset() const {
|
||||
return BaseOffset;
|
||||
}
|
||||
|
||||
bool isVirtual() const {
|
||||
return BaseAndIsVirtual.getInt();
|
||||
}
|
||||
|
||||
BaseSubobject getBaseSubobject() const {
|
||||
return BaseSubobject(getBase(), getBaseOffset());
|
||||
}
|
||||
};
|
||||
|
||||
struct VTTComponent {
|
||||
uint64_t VTableIndex;
|
||||
BaseSubobject VTableBase;
|
||||
|
||||
VTTComponent() {}
|
||||
VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
|
||||
: VTableIndex(VTableIndex), VTableBase(VTableBase) {}
|
||||
};
|
||||
|
||||
/// VTT builder - Class for building VTT layout information.
|
||||
class VTTBuilder {
|
||||
|
||||
ASTContext &Ctx;
|
||||
|
||||
/// MostDerivedClass - The most derived class for which we're building this
|
||||
/// vtable.
|
||||
const CXXRecordDecl *MostDerivedClass;
|
||||
|
||||
typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
|
||||
|
||||
/// VTTVTables - The VTT vtables.
|
||||
VTTVTablesVectorTy VTTVTables;
|
||||
|
||||
typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
|
||||
|
||||
/// VTTComponents - The VTT components.
|
||||
VTTComponentsVectorTy VTTComponents;
|
||||
|
||||
/// MostDerivedClassLayout - the AST record layout of the most derived class.
|
||||
const ASTRecordLayout &MostDerivedClassLayout;
|
||||
|
||||
typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
|
||||
|
||||
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
|
||||
|
||||
/// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
|
||||
/// class.
|
||||
llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
|
||||
|
||||
/// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
|
||||
/// all subobjects of the most derived class.
|
||||
llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
|
||||
|
||||
/// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
|
||||
/// the VTT.
|
||||
bool GenerateDefinition;
|
||||
|
||||
/// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
|
||||
void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
|
||||
const CXXRecordDecl *VTableClass);
|
||||
|
||||
/// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
|
||||
/// subobject.
|
||||
void LayoutSecondaryVTTs(BaseSubobject Base);
|
||||
|
||||
/// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
|
||||
/// for the given base subobject.
|
||||
///
|
||||
/// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
|
||||
/// or a direct or indirect base of a virtual base.
|
||||
void LayoutSecondaryVirtualPointers(BaseSubobject Base,
|
||||
bool BaseIsMorallyVirtual,
|
||||
uint64_t VTableIndex,
|
||||
const CXXRecordDecl *VTableClass,
|
||||
VisitedVirtualBasesSetTy &VBases);
|
||||
|
||||
/// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
|
||||
/// for the given base subobject.
|
||||
void LayoutSecondaryVirtualPointers(BaseSubobject Base,
|
||||
uint64_t VTableIndex);
|
||||
|
||||
/// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
|
||||
/// given record decl.
|
||||
void LayoutVirtualVTTs(const CXXRecordDecl *RD,
|
||||
VisitedVirtualBasesSetTy &VBases);
|
||||
|
||||
/// LayoutVTT - Will lay out the VTT for the given subobject, including any
|
||||
/// secondary VTTs, secondary virtual pointers and virtual VTTs.
|
||||
void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
|
||||
|
||||
public:
|
||||
VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
|
||||
bool GenerateDefinition);
|
||||
|
||||
// getVTTComponents - Returns a reference to the VTT components.
|
||||
const VTTComponentsVectorTy &getVTTComponents() const {
|
||||
return VTTComponents;
|
||||
}
|
||||
|
||||
// getVTTVTables - Returns a reference to the VTT vtables.
|
||||
const VTTVTablesVectorTy &getVTTVTables() const {
|
||||
return VTTVTables;
|
||||
}
|
||||
|
||||
/// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
|
||||
const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
|
||||
return SubVTTIndicies;
|
||||
}
|
||||
|
||||
/// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
|
||||
/// virtual pointer indices.
|
||||
const llvm::DenseMap<BaseSubobject, uint64_t> &
|
||||
getSecondaryVirtualPointerIndices() const {
|
||||
return SecondaryVirtualPointerIndices;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
375
thirdparty/clang/include/clang/AST/VTableBuilder.h
vendored
Normal file
375
thirdparty/clang/include/clang/AST/VTableBuilder.h
vendored
Normal file
@@ -0,0 +1,375 @@
|
||||
//===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This contains code dealing with generation of the layout of virtual tables.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_VTABLEBUILDER_H
|
||||
#define LLVM_CLANG_AST_VTABLEBUILDER_H
|
||||
|
||||
#include "clang/AST/BaseSubobject.h"
|
||||
#include "clang/AST/CXXInheritance.h"
|
||||
#include "clang/AST/GlobalDecl.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
class CXXRecordDecl;
|
||||
|
||||
/// VTableComponent - Represents a single component in a vtable.
|
||||
class VTableComponent {
|
||||
public:
|
||||
enum Kind {
|
||||
CK_VCallOffset,
|
||||
CK_VBaseOffset,
|
||||
CK_OffsetToTop,
|
||||
CK_RTTI,
|
||||
CK_FunctionPointer,
|
||||
|
||||
/// CK_CompleteDtorPointer - A pointer to the complete destructor.
|
||||
CK_CompleteDtorPointer,
|
||||
|
||||
/// CK_DeletingDtorPointer - A pointer to the deleting destructor.
|
||||
CK_DeletingDtorPointer,
|
||||
|
||||
/// CK_UnusedFunctionPointer - In some cases, a vtable function pointer
|
||||
/// will end up never being called. Such vtable function pointers are
|
||||
/// represented as a CK_UnusedFunctionPointer.
|
||||
CK_UnusedFunctionPointer
|
||||
};
|
||||
|
||||
VTableComponent() { }
|
||||
|
||||
static VTableComponent MakeVCallOffset(CharUnits Offset) {
|
||||
return VTableComponent(CK_VCallOffset, Offset);
|
||||
}
|
||||
|
||||
static VTableComponent MakeVBaseOffset(CharUnits Offset) {
|
||||
return VTableComponent(CK_VBaseOffset, Offset);
|
||||
}
|
||||
|
||||
static VTableComponent MakeOffsetToTop(CharUnits Offset) {
|
||||
return VTableComponent(CK_OffsetToTop, Offset);
|
||||
}
|
||||
|
||||
static VTableComponent MakeRTTI(const CXXRecordDecl *RD) {
|
||||
return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
|
||||
}
|
||||
|
||||
static VTableComponent MakeFunction(const CXXMethodDecl *MD) {
|
||||
assert(!isa<CXXDestructorDecl>(MD) &&
|
||||
"Don't use MakeFunction with destructors!");
|
||||
|
||||
return VTableComponent(CK_FunctionPointer,
|
||||
reinterpret_cast<uintptr_t>(MD));
|
||||
}
|
||||
|
||||
static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) {
|
||||
return VTableComponent(CK_CompleteDtorPointer,
|
||||
reinterpret_cast<uintptr_t>(DD));
|
||||
}
|
||||
|
||||
static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) {
|
||||
return VTableComponent(CK_DeletingDtorPointer,
|
||||
reinterpret_cast<uintptr_t>(DD));
|
||||
}
|
||||
|
||||
static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) {
|
||||
assert(!isa<CXXDestructorDecl>(MD) &&
|
||||
"Don't use MakeUnusedFunction with destructors!");
|
||||
return VTableComponent(CK_UnusedFunctionPointer,
|
||||
reinterpret_cast<uintptr_t>(MD));
|
||||
}
|
||||
|
||||
static VTableComponent getFromOpaqueInteger(uint64_t I) {
|
||||
return VTableComponent(I);
|
||||
}
|
||||
|
||||
/// getKind - Get the kind of this vtable component.
|
||||
Kind getKind() const {
|
||||
return (Kind)(Value & 0x7);
|
||||
}
|
||||
|
||||
CharUnits getVCallOffset() const {
|
||||
assert(getKind() == CK_VCallOffset && "Invalid component kind!");
|
||||
|
||||
return getOffset();
|
||||
}
|
||||
|
||||
CharUnits getVBaseOffset() const {
|
||||
assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
|
||||
|
||||
return getOffset();
|
||||
}
|
||||
|
||||
CharUnits getOffsetToTop() const {
|
||||
assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
|
||||
|
||||
return getOffset();
|
||||
}
|
||||
|
||||
const CXXRecordDecl *getRTTIDecl() const {
|
||||
assert(getKind() == CK_RTTI && "Invalid component kind!");
|
||||
|
||||
return reinterpret_cast<CXXRecordDecl *>(getPointer());
|
||||
}
|
||||
|
||||
const CXXMethodDecl *getFunctionDecl() const {
|
||||
assert(getKind() == CK_FunctionPointer);
|
||||
|
||||
return reinterpret_cast<CXXMethodDecl *>(getPointer());
|
||||
}
|
||||
|
||||
const CXXDestructorDecl *getDestructorDecl() const {
|
||||
assert((getKind() == CK_CompleteDtorPointer ||
|
||||
getKind() == CK_DeletingDtorPointer) && "Invalid component kind!");
|
||||
|
||||
return reinterpret_cast<CXXDestructorDecl *>(getPointer());
|
||||
}
|
||||
|
||||
const CXXMethodDecl *getUnusedFunctionDecl() const {
|
||||
assert(getKind() == CK_UnusedFunctionPointer);
|
||||
|
||||
return reinterpret_cast<CXXMethodDecl *>(getPointer());
|
||||
}
|
||||
|
||||
private:
|
||||
VTableComponent(Kind ComponentKind, CharUnits Offset) {
|
||||
assert((ComponentKind == CK_VCallOffset ||
|
||||
ComponentKind == CK_VBaseOffset ||
|
||||
ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
|
||||
assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!");
|
||||
assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!");
|
||||
|
||||
Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind;
|
||||
}
|
||||
|
||||
VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
|
||||
assert((ComponentKind == CK_RTTI ||
|
||||
ComponentKind == CK_FunctionPointer ||
|
||||
ComponentKind == CK_CompleteDtorPointer ||
|
||||
ComponentKind == CK_DeletingDtorPointer ||
|
||||
ComponentKind == CK_UnusedFunctionPointer) &&
|
||||
"Invalid component kind!");
|
||||
|
||||
assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
|
||||
|
||||
Value = Ptr | ComponentKind;
|
||||
}
|
||||
|
||||
CharUnits getOffset() const {
|
||||
assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
|
||||
getKind() == CK_OffsetToTop) && "Invalid component kind!");
|
||||
|
||||
return CharUnits::fromQuantity(Value >> 3);
|
||||
}
|
||||
|
||||
uintptr_t getPointer() const {
|
||||
assert((getKind() == CK_RTTI ||
|
||||
getKind() == CK_FunctionPointer ||
|
||||
getKind() == CK_CompleteDtorPointer ||
|
||||
getKind() == CK_DeletingDtorPointer ||
|
||||
getKind() == CK_UnusedFunctionPointer) &&
|
||||
"Invalid component kind!");
|
||||
|
||||
return static_cast<uintptr_t>(Value & ~7ULL);
|
||||
}
|
||||
|
||||
explicit VTableComponent(uint64_t Value)
|
||||
: Value(Value) { }
|
||||
|
||||
/// The kind is stored in the lower 3 bits of the value. For offsets, we
|
||||
/// make use of the facts that classes can't be larger than 2^55 bytes,
|
||||
/// so we store the offset in the lower part of the 61 bytes that remain.
|
||||
/// (The reason that we're not simply using a PointerIntPair here is that we
|
||||
/// need the offsets to be 64-bit, even when on a 32-bit machine).
|
||||
int64_t Value;
|
||||
};
|
||||
|
||||
class VTableLayout {
|
||||
public:
|
||||
typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
|
||||
typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
|
||||
|
||||
typedef const VTableComponent *vtable_component_iterator;
|
||||
typedef const VTableThunkTy *vtable_thunk_iterator;
|
||||
|
||||
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
|
||||
private:
|
||||
uint64_t NumVTableComponents;
|
||||
llvm::OwningArrayPtr<VTableComponent> VTableComponents;
|
||||
|
||||
/// VTableThunks - Contains thunks needed by vtables.
|
||||
uint64_t NumVTableThunks;
|
||||
llvm::OwningArrayPtr<VTableThunkTy> VTableThunks;
|
||||
|
||||
/// Address points - Address points for all vtables.
|
||||
AddressPointsMapTy AddressPoints;
|
||||
|
||||
bool IsMicrosoftABI;
|
||||
|
||||
public:
|
||||
VTableLayout(uint64_t NumVTableComponents,
|
||||
const VTableComponent *VTableComponents,
|
||||
uint64_t NumVTableThunks,
|
||||
const VTableThunkTy *VTableThunks,
|
||||
const AddressPointsMapTy &AddressPoints,
|
||||
bool IsMicrosoftABI);
|
||||
~VTableLayout();
|
||||
|
||||
uint64_t getNumVTableComponents() const {
|
||||
return NumVTableComponents;
|
||||
}
|
||||
|
||||
vtable_component_iterator vtable_component_begin() const {
|
||||
return VTableComponents.get();
|
||||
}
|
||||
|
||||
vtable_component_iterator vtable_component_end() const {
|
||||
return VTableComponents.get()+NumVTableComponents;
|
||||
}
|
||||
|
||||
uint64_t getNumVTableThunks() const {
|
||||
return NumVTableThunks;
|
||||
}
|
||||
|
||||
vtable_thunk_iterator vtable_thunk_begin() const {
|
||||
return VTableThunks.get();
|
||||
}
|
||||
|
||||
vtable_thunk_iterator vtable_thunk_end() const {
|
||||
return VTableThunks.get()+NumVTableThunks;
|
||||
}
|
||||
|
||||
uint64_t getAddressPoint(BaseSubobject Base) const {
|
||||
assert(AddressPoints.count(Base) &&
|
||||
"Did not find address point!");
|
||||
|
||||
uint64_t AddressPoint = AddressPoints.lookup(Base);
|
||||
assert(AddressPoint != 0 || IsMicrosoftABI);
|
||||
(void)IsMicrosoftABI;
|
||||
|
||||
return AddressPoint;
|
||||
}
|
||||
|
||||
const AddressPointsMapTy &getAddressPoints() const {
|
||||
return AddressPoints;
|
||||
}
|
||||
};
|
||||
|
||||
class VTableContext {
|
||||
ASTContext &Context;
|
||||
|
||||
public:
|
||||
typedef SmallVector<std::pair<uint64_t, ThunkInfo>, 1>
|
||||
VTableThunksTy;
|
||||
typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
|
||||
|
||||
private:
|
||||
bool IsMicrosoftABI;
|
||||
|
||||
/// MethodVTableIndices - Contains the index (relative to the vtable address
|
||||
/// point) where the function pointer for a virtual function is stored.
|
||||
typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
|
||||
MethodVTableIndicesTy MethodVTableIndices;
|
||||
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, const VTableLayout *>
|
||||
VTableLayoutMapTy;
|
||||
VTableLayoutMapTy VTableLayouts;
|
||||
|
||||
/// NumVirtualFunctionPointers - Contains the number of virtual function
|
||||
/// pointers in the vtable for a given record decl.
|
||||
llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
|
||||
|
||||
typedef std::pair<const CXXRecordDecl *,
|
||||
const CXXRecordDecl *> ClassPairTy;
|
||||
|
||||
/// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to
|
||||
/// the address point) in chars where the offsets for virtual bases of a class
|
||||
/// are stored.
|
||||
typedef llvm::DenseMap<ClassPairTy, CharUnits>
|
||||
VirtualBaseClassOffsetOffsetsMapTy;
|
||||
VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
|
||||
|
||||
typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
|
||||
|
||||
/// Thunks - Contains all thunks that a given method decl will need.
|
||||
ThunksMapTy Thunks;
|
||||
|
||||
void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
|
||||
|
||||
/// ComputeVTableRelatedInformation - Compute and store all vtable related
|
||||
/// information (vtable layout, vbase offset offsets, thunks etc) for the
|
||||
/// given record decl.
|
||||
void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
|
||||
|
||||
/// ErrorUnsupported - Print out an error that the v-table layout code
|
||||
/// doesn't support the particular C++ feature yet.
|
||||
void ErrorUnsupported(StringRef Feature, SourceLocation Location);
|
||||
|
||||
public:
|
||||
VTableContext(ASTContext &Context);
|
||||
~VTableContext();
|
||||
|
||||
bool isMicrosoftABI() const {
|
||||
// FIXME: Currently, this method is only used in the VTableContext and
|
||||
// VTableBuilder code which is ABI-specific. Probably we can remove it
|
||||
// when we add a layer of abstraction for vtable generation.
|
||||
return IsMicrosoftABI;
|
||||
}
|
||||
|
||||
const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {
|
||||
ComputeVTableRelatedInformation(RD);
|
||||
assert(VTableLayouts.count(RD) && "No layout for this record decl!");
|
||||
|
||||
return *VTableLayouts[RD];
|
||||
}
|
||||
|
||||
VTableLayout *
|
||||
createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass,
|
||||
CharUnits MostDerivedClassOffset,
|
||||
bool MostDerivedClassIsVirtual,
|
||||
const CXXRecordDecl *LayoutClass);
|
||||
|
||||
const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) {
|
||||
ComputeVTableRelatedInformation(MD->getParent());
|
||||
|
||||
ThunksMapTy::const_iterator I = Thunks.find(MD);
|
||||
if (I == Thunks.end()) {
|
||||
// We did not find a thunk for this method.
|
||||
return 0;
|
||||
}
|
||||
|
||||
return &I->second;
|
||||
}
|
||||
|
||||
/// getNumVirtualFunctionPointers - Return the number of virtual function
|
||||
/// pointers in the vtable for a given record decl.
|
||||
uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
|
||||
|
||||
/// getMethodVTableIndex - Return the index (relative to the vtable address
|
||||
/// point) where the function pointer for the given virtual function is
|
||||
/// stored.
|
||||
uint64_t getMethodVTableIndex(GlobalDecl GD);
|
||||
|
||||
/// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the
|
||||
/// vtable address point) where the offset of the virtual base that contains
|
||||
/// the given base is stored, otherwise, if no virtual base contains the given
|
||||
/// class, return 0. Base must be a virtual base class or an unambigious
|
||||
/// base.
|
||||
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *VBase);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
239
thirdparty/clang/include/clang/ASTMatchers/ASTMatchFinder.h
vendored
Normal file
239
thirdparty/clang/include/clang/ASTMatchers/ASTMatchFinder.h
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
//===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Provides a way to construct an ASTConsumer that runs given matchers
|
||||
// over the AST and invokes a given callback on every match.
|
||||
//
|
||||
// The general idea is to construct a matcher expression that describes a
|
||||
// subtree match on the AST. Next, a callback that is executed every time the
|
||||
// expression matches is registered, and the matcher is run over the AST of
|
||||
// some code. Matched subexpressions can be bound to string IDs and easily
|
||||
// be accessed from the registered callback. The callback can than use the
|
||||
// AST nodes that the subexpressions matched on to output information about
|
||||
// the match or construct changes that can be applied to the code.
|
||||
//
|
||||
// Example:
|
||||
// class HandleMatch : public MatchFinder::MatchCallback {
|
||||
// public:
|
||||
// virtual void Run(const MatchFinder::MatchResult &Result) {
|
||||
// const CXXRecordDecl *Class =
|
||||
// Result.Nodes.GetDeclAs<CXXRecordDecl>("id");
|
||||
// ...
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// int main(int argc, char **argv) {
|
||||
// ClangTool Tool(argc, argv);
|
||||
// MatchFinder finder;
|
||||
// finder.AddMatcher(Id("id", record(hasName("::a_namespace::AClass"))),
|
||||
// new HandleMatch);
|
||||
// return Tool.Run(newFrontendActionFactory(&finder));
|
||||
// }
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
|
||||
#define LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
|
||||
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace ast_matchers {
|
||||
|
||||
/// \brief A class to allow finding matches over the Clang AST.
|
||||
///
|
||||
/// After creation, you can add multiple matchers to the MatchFinder via
|
||||
/// calls to addMatcher(...).
|
||||
///
|
||||
/// Once all matchers are added, newASTConsumer() returns an ASTConsumer
|
||||
/// that will trigger the callbacks specified via addMatcher(...) when a match
|
||||
/// is found.
|
||||
///
|
||||
/// The order of matches is guaranteed to be equivalent to doing a pre-order
|
||||
/// traversal on the AST, and applying the matchers in the order in which they
|
||||
/// were added to the MatchFinder.
|
||||
///
|
||||
/// See ASTMatchers.h for more information about how to create matchers.
|
||||
///
|
||||
/// Not intended to be subclassed.
|
||||
class MatchFinder {
|
||||
public:
|
||||
/// \brief Contains all information for a given match.
|
||||
///
|
||||
/// Every time a match is found, the MatchFinder will invoke the registered
|
||||
/// MatchCallback with a MatchResult containing information about the match.
|
||||
struct MatchResult {
|
||||
MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context);
|
||||
|
||||
/// \brief Contains the nodes bound on the current match.
|
||||
///
|
||||
/// This allows user code to easily extract matched AST nodes.
|
||||
const BoundNodes Nodes;
|
||||
|
||||
/// \brief Utilities for interpreting the matched AST structures.
|
||||
/// @{
|
||||
clang::ASTContext * const Context;
|
||||
clang::SourceManager * const SourceManager;
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// \brief Called when the Match registered for it was successfully found
|
||||
/// in the AST.
|
||||
class MatchCallback {
|
||||
public:
|
||||
virtual ~MatchCallback();
|
||||
|
||||
/// \brief Called on every match by the \c MatchFinder.
|
||||
virtual void run(const MatchResult &Result) = 0;
|
||||
|
||||
/// \brief Called at the start of each translation unit.
|
||||
///
|
||||
/// Optionally override to do per translation unit tasks.
|
||||
virtual void onStartOfTranslationUnit() {}
|
||||
};
|
||||
|
||||
/// \brief Called when parsing is finished. Intended for testing only.
|
||||
class ParsingDoneTestCallback {
|
||||
public:
|
||||
virtual ~ParsingDoneTestCallback();
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
MatchFinder();
|
||||
~MatchFinder();
|
||||
|
||||
/// \brief Adds a matcher to execute when running over the AST.
|
||||
///
|
||||
/// Calls 'Action' with the BoundNodes on every match.
|
||||
/// Adding more than one 'NodeMatch' allows finding different matches in a
|
||||
/// single pass over the AST.
|
||||
///
|
||||
/// Does not take ownership of 'Action'.
|
||||
/// @{
|
||||
void addMatcher(const DeclarationMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
void addMatcher(const TypeMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
void addMatcher(const StatementMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
void addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
void addMatcher(const TypeLocMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
/// @}
|
||||
|
||||
/// \brief Creates a clang ASTConsumer that finds all matches.
|
||||
clang::ASTConsumer *newASTConsumer();
|
||||
|
||||
/// \brief Calls the registered callbacks on all matches on the given \p Node.
|
||||
///
|
||||
/// Note that there can be multiple matches on a single node, for
|
||||
/// example when using decl(forEachDescendant(stmt())).
|
||||
///
|
||||
/// @{
|
||||
template <typename T> void match(const T &Node, ASTContext &Context) {
|
||||
match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
|
||||
}
|
||||
void match(const clang::ast_type_traits::DynTypedNode &Node,
|
||||
ASTContext &Context);
|
||||
/// @}
|
||||
|
||||
/// \brief Registers a callback to notify the end of parsing.
|
||||
///
|
||||
/// The provided closure is called after parsing is done, before the AST is
|
||||
/// traversed. Useful for benchmarking.
|
||||
/// Each call to FindAll(...) will call the closure once.
|
||||
void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
|
||||
|
||||
private:
|
||||
/// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called
|
||||
/// when it matches.
|
||||
std::vector<std::pair<const internal::DynTypedMatcher*, MatchCallback*> >
|
||||
MatcherCallbackPairs;
|
||||
|
||||
/// \brief Called when parsing is done.
|
||||
ParsingDoneTestCallback *ParsingDone;
|
||||
};
|
||||
|
||||
/// \brief Returns the results of matching \p Matcher on \p Node.
|
||||
///
|
||||
/// Collects the \c BoundNodes of all callback invocations when matching
|
||||
/// \p Matcher on \p Node and returns the collected results.
|
||||
///
|
||||
/// Multiple results occur when using matchers like \c forEachDescendant,
|
||||
/// which generate a result for each sub-match.
|
||||
///
|
||||
/// \see selectFirst
|
||||
/// @{
|
||||
template <typename MatcherT, typename NodeT>
|
||||
SmallVector<BoundNodes, 1>
|
||||
match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
|
||||
|
||||
template <typename MatcherT>
|
||||
SmallVector<BoundNodes, 1>
|
||||
match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
|
||||
ASTContext &Context);
|
||||
/// @}
|
||||
|
||||
/// \brief Returns the first result of type \c NodeT bound to \p BoundTo.
|
||||
///
|
||||
/// Returns \c NULL if there is no match, or if the matching node cannot be
|
||||
/// casted to \c NodeT.
|
||||
///
|
||||
/// This is useful in combanation with \c match():
|
||||
/// \code
|
||||
/// Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
|
||||
/// Node, Context));
|
||||
/// \endcode
|
||||
template <typename NodeT>
|
||||
NodeT *
|
||||
selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
|
||||
for (SmallVectorImpl<BoundNodes>::const_iterator I = Results.begin(),
|
||||
E = Results.end();
|
||||
I != E; ++I) {
|
||||
if (NodeT *Node = I->getNodeAs<NodeT>(BoundTo))
|
||||
return Node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
class CollectMatchesCallback : public MatchFinder::MatchCallback {
|
||||
public:
|
||||
virtual void run(const MatchFinder::MatchResult &Result) {
|
||||
Nodes.push_back(Result.Nodes);
|
||||
}
|
||||
SmallVector<BoundNodes, 1> Nodes;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename MatcherT>
|
||||
SmallVector<BoundNodes, 1>
|
||||
match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
|
||||
ASTContext &Context) {
|
||||
internal::CollectMatchesCallback Callback;
|
||||
MatchFinder Finder;
|
||||
Finder.addMatcher(Matcher, &Callback);
|
||||
Finder.match(Node, Context);
|
||||
return Callback.Nodes;
|
||||
}
|
||||
|
||||
template <typename MatcherT, typename NodeT>
|
||||
SmallVector<BoundNodes, 1>
|
||||
match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
|
||||
return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
|
||||
}
|
||||
|
||||
} // end namespace ast_matchers
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
|
||||
3337
thirdparty/clang/include/clang/ASTMatchers/ASTMatchers.h
vendored
Normal file
3337
thirdparty/clang/include/clang/ASTMatchers/ASTMatchers.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1245
thirdparty/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
vendored
Normal file
1245
thirdparty/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
345
thirdparty/clang/include/clang/ASTMatchers/ASTMatchersMacros.h
vendored
Normal file
345
thirdparty/clang/include/clang/ASTMatchers/ASTMatchersMacros.h
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
//===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines macros that enable us to define new matchers in a single place.
|
||||
// Since a matcher is a function which returns a Matcher<T> object, where
|
||||
// T is the type of the actual implementation of the matcher, the macros allow
|
||||
// us to write matchers like functions and take care of the definition of the
|
||||
// class boilerplate.
|
||||
//
|
||||
// Note that when you define a matcher with an AST_MATCHER* macro, only the
|
||||
// function which creates the matcher goes into the current namespace - the
|
||||
// class that implements the actual matcher, which gets returned by the
|
||||
// generator function, is put into the 'internal' namespace. This allows us
|
||||
// to only have the functions (which is all the user cares about) in the
|
||||
// 'ast_matchers' namespace and hide the boilerplate.
|
||||
//
|
||||
// To define a matcher in user code, always put it into the clang::ast_matchers
|
||||
// namespace and refer to the internal types via the 'internal::':
|
||||
//
|
||||
// namespace clang {
|
||||
// namespace ast_matchers {
|
||||
// AST_MATCHER_P(MemberExpr, Member,
|
||||
// internal::Matcher<ValueDecl>, InnerMatcher) {
|
||||
// return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
|
||||
// }
|
||||
// } // end namespace ast_matchers
|
||||
// } // end namespace clang
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
|
||||
#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
|
||||
|
||||
/// \brief AST_MATCHER(Type, DefineMatcher) { ... }
|
||||
/// defines a zero parameter function named DefineMatcher() that returns a
|
||||
/// Matcher<Type> object.
|
||||
///
|
||||
/// The code between the curly braces has access to the following variables:
|
||||
///
|
||||
/// Node: the AST node being matched; its type is Type.
|
||||
/// Finder: an ASTMatchFinder*.
|
||||
/// Builder: a BoundNodesTreeBuilder*.
|
||||
///
|
||||
/// The code should return true if 'Node' matches.
|
||||
#define AST_MATCHER(Type, DefineMatcher) \
|
||||
AST_MATCHER_OVERLOAD(Type, DefineMatcher, 0)
|
||||
|
||||
#define AST_MATCHER_OVERLOAD(Type, DefineMatcher, OverloadId) \
|
||||
namespace internal { \
|
||||
class matcher_##DefineMatcher##OverloadId##Matcher \
|
||||
: public MatcherInterface<Type> { \
|
||||
public: \
|
||||
explicit matcher_##DefineMatcher##OverloadId##Matcher() {} \
|
||||
virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const; \
|
||||
}; \
|
||||
} \
|
||||
inline internal::Matcher<Type> DefineMatcher() { \
|
||||
return internal::makeMatcher( \
|
||||
new internal::matcher_##DefineMatcher##OverloadId##Matcher()); \
|
||||
} \
|
||||
inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
|
||||
const Type &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const
|
||||
|
||||
/// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
|
||||
/// defines a single-parameter function named DefineMatcher() that returns a
|
||||
/// Matcher<Type> object.
|
||||
///
|
||||
/// The code between the curly braces has access to the following variables:
|
||||
///
|
||||
/// Node: the AST node being matched; its type is Type.
|
||||
/// Param: the parameter passed to the function; its type
|
||||
/// is ParamType.
|
||||
/// Finder: an ASTMatchFinder*.
|
||||
/// Builder: a BoundNodesTreeBuilder*.
|
||||
///
|
||||
/// The code should return true if 'Node' matches.
|
||||
#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
|
||||
AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
|
||||
|
||||
#define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
|
||||
OverloadId) \
|
||||
namespace internal { \
|
||||
class matcher_##DefineMatcher##OverloadId##Matcher \
|
||||
: public MatcherInterface<Type> { \
|
||||
public: \
|
||||
explicit matcher_##DefineMatcher##OverloadId##Matcher( \
|
||||
const ParamType &A##Param) \
|
||||
: Param(A##Param) { \
|
||||
} \
|
||||
virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const; \
|
||||
private: \
|
||||
const ParamType Param; \
|
||||
}; \
|
||||
} \
|
||||
inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) { \
|
||||
return internal::makeMatcher( \
|
||||
new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
|
||||
} \
|
||||
inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
|
||||
const Type &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const
|
||||
|
||||
/// \brief AST_MATCHER_P2(
|
||||
/// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
|
||||
/// defines a two-parameter function named DefineMatcher() that returns a
|
||||
/// Matcher<Type> object.
|
||||
///
|
||||
/// The code between the curly braces has access to the following variables:
|
||||
///
|
||||
/// Node: the AST node being matched; its type is Type.
|
||||
/// Param1, Param2: the parameters passed to the function; their types
|
||||
/// are ParamType1 and ParamType2.
|
||||
/// Finder: an ASTMatchFinder*.
|
||||
/// Builder: a BoundNodesTreeBuilder*.
|
||||
///
|
||||
/// The code should return true if 'Node' matches.
|
||||
#define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
|
||||
Param2) \
|
||||
AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
|
||||
Param2, 0)
|
||||
|
||||
#define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \
|
||||
ParamType2, Param2, OverloadId) \
|
||||
namespace internal { \
|
||||
class matcher_##DefineMatcher##OverloadId##Matcher \
|
||||
: public MatcherInterface<Type> { \
|
||||
public: \
|
||||
matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
|
||||
const ParamType2 &A##Param2) \
|
||||
: Param1(A##Param1), Param2(A##Param2) { \
|
||||
} \
|
||||
virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const; \
|
||||
private: \
|
||||
const ParamType1 Param1; \
|
||||
const ParamType2 Param2; \
|
||||
}; \
|
||||
} \
|
||||
inline internal::Matcher<Type> \
|
||||
DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
|
||||
return internal::makeMatcher( \
|
||||
new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
|
||||
Param2)); \
|
||||
} \
|
||||
inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
|
||||
const Type &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const
|
||||
|
||||
/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
|
||||
/// defines a single-parameter function named DefineMatcher() that is
|
||||
/// polymorphic in the return type.
|
||||
///
|
||||
/// The variables are the same as for AST_MATCHER, but NodeType will be deduced
|
||||
/// from the calling context.
|
||||
#define AST_POLYMORPHIC_MATCHER(DefineMatcher) \
|
||||
AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, 0)
|
||||
|
||||
#define AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, OverloadId) \
|
||||
namespace internal { \
|
||||
template <typename NodeType> \
|
||||
class matcher_##DefineMatcher##OverloadId##Matcher \
|
||||
: public MatcherInterface<NodeType> { \
|
||||
public: \
|
||||
virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const; \
|
||||
}; \
|
||||
} \
|
||||
inline internal::PolymorphicMatcherWithParam0< \
|
||||
internal::matcher_##DefineMatcher##OverloadId##Matcher> DefineMatcher() {\
|
||||
return internal::PolymorphicMatcherWithParam0< \
|
||||
internal::matcher_##DefineMatcher##OverloadId##Matcher>(); \
|
||||
} \
|
||||
template <typename NodeType> \
|
||||
bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
|
||||
NodeType>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const
|
||||
|
||||
/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
|
||||
/// defines a single-parameter function named DefineMatcher() that is
|
||||
/// polymorphic in the return type.
|
||||
///
|
||||
/// The variables are the same as for
|
||||
/// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
|
||||
/// of the matcher Matcher<NodeType> returned by the function matcher().
|
||||
///
|
||||
/// FIXME: Pull out common code with above macro?
|
||||
#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) \
|
||||
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, 0)
|
||||
|
||||
#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, \
|
||||
OverloadId) \
|
||||
namespace internal { \
|
||||
template <typename NodeType, typename ParamT> \
|
||||
class matcher_##DefineMatcher##OverloadId##Matcher \
|
||||
: public MatcherInterface<NodeType> { \
|
||||
public: \
|
||||
explicit matcher_##DefineMatcher##OverloadId##Matcher( \
|
||||
const ParamType &A##Param) \
|
||||
: Param(A##Param) { \
|
||||
} \
|
||||
virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const; \
|
||||
private: \
|
||||
const ParamType Param; \
|
||||
}; \
|
||||
} \
|
||||
inline internal::PolymorphicMatcherWithParam1< \
|
||||
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType> \
|
||||
DefineMatcher(const ParamType &Param) { \
|
||||
return internal::PolymorphicMatcherWithParam1< \
|
||||
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType>( \
|
||||
Param); \
|
||||
} \
|
||||
template <typename NodeType, typename ParamT> \
|
||||
bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
|
||||
NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const
|
||||
|
||||
/// \brief AST_POLYMORPHIC_MATCHER_P2(
|
||||
/// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
|
||||
/// defines a two-parameter function named matcher() that is polymorphic in
|
||||
/// the return type.
|
||||
///
|
||||
/// The variables are the same as for AST_MATCHER_P2, with the
|
||||
/// addition of NodeType, which specifies the node type of the matcher
|
||||
/// Matcher<NodeType> returned by the function DefineMatcher().
|
||||
#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ParamType1, Param1, \
|
||||
ParamType2, Param2) \
|
||||
AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \
|
||||
ParamType2, Param2, 0)
|
||||
|
||||
#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \
|
||||
ParamType2, Param2, OverloadId) \
|
||||
namespace internal { \
|
||||
template <typename NodeType, typename ParamT1, typename ParamT2> \
|
||||
class matcher_##DefineMatcher##OverloadId##Matcher \
|
||||
: public MatcherInterface<NodeType> { \
|
||||
public: \
|
||||
matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
|
||||
const ParamType2 &A##Param2) \
|
||||
: Param1(A##Param1), Param2(A##Param2) { \
|
||||
} \
|
||||
virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const; \
|
||||
private: \
|
||||
const ParamType1 Param1; \
|
||||
const ParamType2 Param2; \
|
||||
}; \
|
||||
} \
|
||||
inline internal::PolymorphicMatcherWithParam2< \
|
||||
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
|
||||
ParamType2> \
|
||||
DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
|
||||
return internal::PolymorphicMatcherWithParam2< \
|
||||
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
|
||||
ParamType2>(Param1, Param2); \
|
||||
} \
|
||||
template <typename NodeType, typename ParamT1, typename ParamT2> \
|
||||
bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
|
||||
NodeType, ParamT1, ParamT2>::matches( \
|
||||
const NodeType &Node, ASTMatchFinder *Finder, \
|
||||
BoundNodesTreeBuilder *Builder) const
|
||||
|
||||
/// \brief Creates a variadic matcher for both a specific \c Type as well as
|
||||
/// the corresponding \c TypeLoc.
|
||||
#define AST_TYPE_MATCHER(NodeType, MatcherName) \
|
||||
const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
|
||||
// FIXME: add a matcher for TypeLoc derived classes using its custom casting
|
||||
// API (no longer dyn_cast) if/when we need such matching
|
||||
|
||||
/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
|
||||
/// the matcher \c MatcherName that can be used to traverse from one \c Type
|
||||
/// to another.
|
||||
///
|
||||
/// For a specific \c SpecificType, the traversal is done using
|
||||
/// \c SpecificType::FunctionName. The existance of such a function determines
|
||||
/// whether a corresponding matcher can be used on \c SpecificType.
|
||||
#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) \
|
||||
class Polymorphic##MatcherName##TypeMatcher { \
|
||||
public: \
|
||||
Polymorphic##MatcherName##TypeMatcher( \
|
||||
const internal::Matcher<QualType> &InnerMatcher) \
|
||||
: InnerMatcher(InnerMatcher) { \
|
||||
} \
|
||||
template <typename T> operator internal:: Matcher< T>() { \
|
||||
return internal::Matcher<T>(new internal::TypeTraverseMatcher<T>( \
|
||||
InnerMatcher, &T::FunctionName)); \
|
||||
} \
|
||||
private: \
|
||||
const internal::Matcher<QualType> InnerMatcher; \
|
||||
} \
|
||||
; \
|
||||
class Variadic##MatcherName##TypeTraverseMatcher \
|
||||
: public llvm::VariadicFunction< \
|
||||
Polymorphic##MatcherName##TypeMatcher, internal::Matcher<QualType>, \
|
||||
internal::makeTypeAllOfComposite< \
|
||||
Polymorphic##MatcherName##TypeMatcher, QualType> > { \
|
||||
public: \
|
||||
Variadic##MatcherName##TypeTraverseMatcher() { \
|
||||
} \
|
||||
} \
|
||||
; \
|
||||
const Variadic##MatcherName##TypeTraverseMatcher MatcherName
|
||||
|
||||
/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
|
||||
/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
|
||||
#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) \
|
||||
class Polymorphic##MatcherName##TypeLocMatcher { \
|
||||
public: \
|
||||
Polymorphic##MatcherName##TypeLocMatcher( \
|
||||
const internal::Matcher<TypeLoc> &InnerMatcher) \
|
||||
: InnerMatcher(InnerMatcher) { \
|
||||
} \
|
||||
template <typename T> operator internal:: Matcher< T>() { \
|
||||
return internal::Matcher<T>( \
|
||||
new internal::TypeLocTraverseMatcher<T>(InnerMatcher, \
|
||||
&T::FunctionName##Loc)); \
|
||||
} \
|
||||
private: \
|
||||
const internal::Matcher<TypeLoc> InnerMatcher; \
|
||||
} \
|
||||
; \
|
||||
class Variadic##MatcherName##TypeLocTraverseMatcher \
|
||||
: public llvm::VariadicFunction< \
|
||||
Polymorphic##MatcherName##TypeLocMatcher, internal::Matcher<TypeLoc>,\
|
||||
internal::makeTypeAllOfComposite< \
|
||||
Polymorphic##MatcherName##TypeLocMatcher, TypeLoc> > { \
|
||||
public: \
|
||||
Variadic##MatcherName##TypeLocTraverseMatcher() { \
|
||||
} \
|
||||
} \
|
||||
; \
|
||||
const Variadic##MatcherName##TypeLocTraverseMatcher MatcherName##Loc; \
|
||||
AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type)
|
||||
|
||||
#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
|
||||
177
thirdparty/clang/include/clang/ASTMatchers/ASTTypeTraits.h
vendored
Normal file
177
thirdparty/clang/include/clang/ASTMatchers/ASTTypeTraits.h
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
//===--- ASTMatchersTypeTraits.h --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Provides a dynamically typed node container that can be used to store
|
||||
// an AST base node at runtime in the same storage in a type safe way.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
|
||||
#define LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
|
||||
namespace clang {
|
||||
namespace ast_type_traits {
|
||||
|
||||
/// \brief A dynamically typed AST node container.
|
||||
///
|
||||
/// Stores an AST node in a type safe way. This allows writing code that
|
||||
/// works with different kinds of AST nodes, despite the fact that they don't
|
||||
/// have a common base class.
|
||||
///
|
||||
/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
|
||||
/// and \c get<T>() to retrieve the node as type T if the types match.
|
||||
///
|
||||
/// See \c NodeTypeTag for which node base types are currently supported;
|
||||
/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
|
||||
/// the supported base types.
|
||||
class DynTypedNode {
|
||||
public:
|
||||
/// \brief Creates a \c DynTypedNode from \c Node.
|
||||
template <typename T>
|
||||
static DynTypedNode create(const T &Node) {
|
||||
return BaseConverter<T>::create(Node);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the stored node as type \c T.
|
||||
///
|
||||
/// Returns NULL if the stored node does not have a type that is
|
||||
/// convertible to \c T.
|
||||
///
|
||||
/// For types that have identity via their pointer in the AST
|
||||
/// (like \c Stmt and \c Decl) the returned pointer points to the
|
||||
/// referenced AST node.
|
||||
/// For other types (like \c QualType) the value is stored directly
|
||||
/// in the \c DynTypedNode, and the returned pointer points at
|
||||
/// the storage inside DynTypedNode. For those nodes, do not
|
||||
/// use the pointer outside the scope of the DynTypedNode.
|
||||
template <typename T>
|
||||
const T *get() const {
|
||||
return BaseConverter<T>::get(Tag, Storage.buffer);
|
||||
}
|
||||
|
||||
/// \brief Returns a pointer that identifies the stored AST node.
|
||||
///
|
||||
/// Note that this is not supported by all AST nodes. For AST nodes
|
||||
/// that don't have a pointer-defined identity inside the AST, this
|
||||
/// method returns NULL.
|
||||
const void *getMemoizationData() const;
|
||||
|
||||
private:
|
||||
/// \brief Takes care of converting from and to \c T.
|
||||
template <typename T, typename EnablerT = void> struct BaseConverter;
|
||||
|
||||
/// \brief Supported base node types.
|
||||
enum NodeTypeTag {
|
||||
NT_Decl,
|
||||
NT_Stmt,
|
||||
NT_NestedNameSpecifier,
|
||||
NT_NestedNameSpecifierLoc,
|
||||
NT_QualType
|
||||
} Tag;
|
||||
|
||||
/// \brief Stores the data of the node.
|
||||
///
|
||||
/// Note that we can store \c Decls and \c Stmts by pointer as they are
|
||||
/// guaranteed to be unique pointers pointing to dedicated storage in the
|
||||
/// AST. \c QualTypes on the other hand do not have storage or unique
|
||||
/// pointers and thus need to be stored by value.
|
||||
llvm::AlignedCharArrayUnion<Decl*, Stmt*, NestedNameSpecifierLoc, QualType> Storage;
|
||||
};
|
||||
template<typename T> struct DynTypedNode::BaseConverter<T,
|
||||
typename llvm::enable_if<llvm::is_base_of<Decl, T> >::type> {
|
||||
static const T *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_Decl)
|
||||
return dyn_cast<T>(*reinterpret_cast<Decl*const*>(Storage));
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const Decl &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_Decl;
|
||||
new (Result.Storage.buffer) const Decl*(&Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<typename T> struct DynTypedNode::BaseConverter<T,
|
||||
typename llvm::enable_if<llvm::is_base_of<Stmt, T> >::type> {
|
||||
static const T *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_Stmt)
|
||||
return dyn_cast<T>(*reinterpret_cast<Stmt*const*>(Storage));
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const Stmt &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_Stmt;
|
||||
new (Result.Storage.buffer) const Stmt*(&Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<> struct DynTypedNode::BaseConverter<NestedNameSpecifier, void> {
|
||||
static const NestedNameSpecifier *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_NestedNameSpecifier)
|
||||
return *reinterpret_cast<NestedNameSpecifier*const*>(Storage);
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const NestedNameSpecifier &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_NestedNameSpecifier;
|
||||
new (Result.Storage.buffer) const NestedNameSpecifier*(&Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<> struct DynTypedNode::BaseConverter<NestedNameSpecifierLoc, void> {
|
||||
static const NestedNameSpecifierLoc *get(NodeTypeTag Tag,
|
||||
const char Storage[]) {
|
||||
if (Tag == NT_NestedNameSpecifierLoc)
|
||||
return reinterpret_cast<const NestedNameSpecifierLoc*>(Storage);
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const NestedNameSpecifierLoc &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_NestedNameSpecifierLoc;
|
||||
new (Result.Storage.buffer) NestedNameSpecifierLoc(Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
template<> struct DynTypedNode::BaseConverter<QualType, void> {
|
||||
static const QualType *get(NodeTypeTag Tag, const char Storage[]) {
|
||||
if (Tag == NT_QualType)
|
||||
return reinterpret_cast<const QualType*>(Storage);
|
||||
return NULL;
|
||||
}
|
||||
static DynTypedNode create(const QualType &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.Tag = NT_QualType;
|
||||
new (Result.Storage.buffer) QualType(Node);
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
// The only operation we allow on unsupported types is \c get.
|
||||
// This allows to conveniently use \c DynTypedNode when having an arbitrary
|
||||
// AST node that is not supported, but prevents misuse - a user cannot create
|
||||
// a DynTypedNode from arbitrary types.
|
||||
template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
|
||||
static const T *get(NodeTypeTag Tag, const char Storage[]) { return NULL; }
|
||||
};
|
||||
|
||||
inline const void *DynTypedNode::getMemoizationData() const {
|
||||
switch (Tag) {
|
||||
case NT_Decl: return BaseConverter<Decl>::get(Tag, Storage.buffer);
|
||||
case NT_Stmt: return BaseConverter<Stmt>::get(Tag, Storage.buffer);
|
||||
default: return NULL;
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace ast_type_traits
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
|
||||
49
thirdparty/clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
vendored
Normal file
49
thirdparty/clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
//==- CFGReachabilityAnalysis.h - Basic reachability analysis ----*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a flow-sensitive, (mostly) path-insensitive reachability
|
||||
// analysis based on Clang's CFGs. Clients can query if a given basic block
|
||||
// is reachable within the CFG.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_ANALYSIS_CFG_REACHABILITY
|
||||
#define CLANG_ANALYSIS_CFG_REACHABILITY
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CFG;
|
||||
class CFGBlock;
|
||||
|
||||
// A class that performs reachability queries for CFGBlocks. Several internal
|
||||
// checks in this checker require reachability information. The requests all
|
||||
// tend to have a common destination, so we lazily do a predecessor search
|
||||
// from the destination node and cache the results to prevent work
|
||||
// duplication.
|
||||
class CFGReverseBlockReachabilityAnalysis {
|
||||
typedef llvm::BitVector ReachableSet;
|
||||
typedef llvm::DenseMap<unsigned, ReachableSet> ReachableMap;
|
||||
ReachableSet analyzed;
|
||||
ReachableMap reachable;
|
||||
public:
|
||||
CFGReverseBlockReachabilityAnalysis(const CFG &cfg);
|
||||
|
||||
/// Returns true if the block 'Dst' can be reached from block 'Src'.
|
||||
bool isReachable(const CFGBlock *Src, const CFGBlock *Dst);
|
||||
|
||||
private:
|
||||
void mapReachability(const CFGBlock *Dst);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
211
thirdparty/clang/include/clang/Analysis/Analyses/Dominators.h
vendored
Normal file
211
thirdparty/clang/include/clang/Analysis/Analyses/Dominators.h
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
//==- Dominators.h - Implementation of dominators tree for Clang CFG C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the dominators tree functionality for Clang CFGs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_DOMINATORS_H
|
||||
#define LLVM_CLANG_DOMINATORS_H
|
||||
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/Analysis/DominatorInternals.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CFGBlock;
|
||||
typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
|
||||
|
||||
/// \brief Concrete subclass of DominatorTreeBase for Clang
|
||||
/// This class implements the dominators tree functionality given a Clang CFG.
|
||||
///
|
||||
class DominatorTree : public ManagedAnalysis {
|
||||
virtual void anchor();
|
||||
public:
|
||||
llvm::DominatorTreeBase<CFGBlock>* DT;
|
||||
|
||||
DominatorTree() {
|
||||
DT = new llvm::DominatorTreeBase<CFGBlock>(false);
|
||||
}
|
||||
|
||||
~DominatorTree() {
|
||||
delete DT;
|
||||
}
|
||||
|
||||
llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
|
||||
|
||||
/// \brief This method returns the root CFGBlock of the dominators tree.
|
||||
///
|
||||
inline CFGBlock *getRoot() const {
|
||||
return DT->getRoot();
|
||||
}
|
||||
|
||||
/// \brief This method returns the root DomTreeNode, which is the wrapper
|
||||
/// for CFGBlock.
|
||||
inline DomTreeNode *getRootNode() const {
|
||||
return DT->getRootNode();
|
||||
}
|
||||
|
||||
/// \brief This method compares two dominator trees.
|
||||
/// The method returns false if the other dominator tree matches this
|
||||
/// dominator tree, otherwise returns true.
|
||||
///
|
||||
inline bool compare(DominatorTree &Other) const {
|
||||
DomTreeNode *R = getRootNode();
|
||||
DomTreeNode *OtherR = Other.getRootNode();
|
||||
|
||||
if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
|
||||
return true;
|
||||
|
||||
if (DT->compare(Other.getBase()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief This method builds the dominator tree for a given CFG
|
||||
/// The CFG information is passed via AnalysisDeclContext
|
||||
///
|
||||
void buildDominatorTree(AnalysisDeclContext &AC) {
|
||||
cfg = AC.getCFG();
|
||||
DT->recalculate(*cfg);
|
||||
}
|
||||
|
||||
/// \brief This method dumps immediate dominators for each block,
|
||||
/// mainly used for debug purposes.
|
||||
///
|
||||
void dump() {
|
||||
llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
|
||||
for (CFG::const_iterator I = cfg->begin(),
|
||||
E = cfg->end(); I != E; ++I) {
|
||||
if(DT->getNode(*I)->getIDom())
|
||||
llvm::errs() << "(" << (*I)->getBlockID()
|
||||
<< ","
|
||||
<< DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
|
||||
<< ")\n";
|
||||
else llvm::errs() << "(" << (*I)->getBlockID()
|
||||
<< "," << (*I)->getBlockID() << ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief This method tests if one CFGBlock dominates the other.
|
||||
/// The method return true if A dominates B, false otherwise.
|
||||
/// Note a block always dominates itself.
|
||||
///
|
||||
inline bool dominates(const CFGBlock* A, const CFGBlock* B) const {
|
||||
return DT->dominates(A, B);
|
||||
}
|
||||
|
||||
/// \brief This method tests if one CFGBlock properly dominates the other.
|
||||
/// The method return true if A properly dominates B, false otherwise.
|
||||
///
|
||||
bool properlyDominates(const CFGBlock*A, const CFGBlock*B) const {
|
||||
return DT->properlyDominates(A, B);
|
||||
}
|
||||
|
||||
/// \brief This method finds the nearest common dominator CFG block
|
||||
/// for CFG block A and B. If there is no such block then return NULL.
|
||||
///
|
||||
inline CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
|
||||
return DT->findNearestCommonDominator(A, B);
|
||||
}
|
||||
|
||||
inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
|
||||
const CFGBlock *B) {
|
||||
return DT->findNearestCommonDominator(A, B);
|
||||
}
|
||||
|
||||
/// \brief This method is used to update the dominator
|
||||
/// tree information when a node's immediate dominator changes.
|
||||
///
|
||||
inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
|
||||
DT->changeImmediateDominator(N, NewIDom);
|
||||
}
|
||||
|
||||
/// \brief This method tests if the given CFGBlock can be reachable from root.
|
||||
/// Returns true if reachable, false otherwise.
|
||||
///
|
||||
bool isReachableFromEntry(const CFGBlock *A) {
|
||||
return DT->isReachableFromEntry(A);
|
||||
}
|
||||
|
||||
/// \brief This method releases the memory held by the dominator tree.
|
||||
///
|
||||
virtual void releaseMemory() {
|
||||
DT->releaseMemory();
|
||||
}
|
||||
|
||||
/// \brief This method converts the dominator tree to human readable form.
|
||||
///
|
||||
virtual void print(raw_ostream &OS, const llvm::Module* M= 0) const {
|
||||
DT->print(OS);
|
||||
}
|
||||
|
||||
private:
|
||||
CFG *cfg;
|
||||
};
|
||||
|
||||
inline void WriteAsOperand(raw_ostream &OS, const CFGBlock *BB,
|
||||
bool t) {
|
||||
OS << "BB#" << BB->getBlockID();
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
//===-------------------------------------
|
||||
/// DominatorTree GraphTraits specialization so the DominatorTree can be
|
||||
/// iterable by generic graph iterators.
|
||||
///
|
||||
namespace llvm {
|
||||
template <> struct GraphTraits< ::clang::DomTreeNode* > {
|
||||
typedef ::clang::DomTreeNode NodeType;
|
||||
typedef NodeType::iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(NodeType *N) {
|
||||
return N;
|
||||
}
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
return N->begin();
|
||||
}
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
return N->end();
|
||||
}
|
||||
|
||||
typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
|
||||
|
||||
static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
|
||||
return df_begin(getEntryNode(N));
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
|
||||
return df_end(getEntryNode(N));
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GraphTraits< ::clang::DominatorTree* >
|
||||
: public GraphTraits< ::clang::DomTreeNode* > {
|
||||
static NodeType *getEntryNode(::clang::DominatorTree *DT) {
|
||||
return DT->getRootNode();
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
|
||||
return df_begin(getEntryNode(N));
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end(::clang::DominatorTree *N) {
|
||||
return df_end(getEntryNode(N));
|
||||
}
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
645
thirdparty/clang/include/clang/Analysis/Analyses/FormatString.h
vendored
Normal file
645
thirdparty/clang/include/clang/Analysis/Analyses/FormatString.h
vendored
Normal file
@@ -0,0 +1,645 @@
|
||||
//= FormatString.h - Analysis of printf/fprintf format strings --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines APIs for analyzing the format strings of printf, fscanf,
|
||||
// and friends.
|
||||
//
|
||||
// The structure of format strings for fprintf are described in C99 7.19.6.1.
|
||||
//
|
||||
// The structure of format strings for fscanf are described in C99 7.19.6.2.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FORMAT_H
|
||||
#define LLVM_CLANG_FORMAT_H
|
||||
|
||||
#include "clang/AST/CanonicalType.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class TargetInfo;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// Common components of both fprintf and fscanf format strings.
|
||||
namespace analyze_format_string {
|
||||
|
||||
/// Class representing optional flags with location and representation
|
||||
/// information.
|
||||
class OptionalFlag {
|
||||
public:
|
||||
OptionalFlag(const char *Representation)
|
||||
: representation(Representation), flag(false) {}
|
||||
bool isSet() { return flag; }
|
||||
void set() { flag = true; }
|
||||
void clear() { flag = false; }
|
||||
void setPosition(const char *position) {
|
||||
assert(position);
|
||||
this->position = position;
|
||||
}
|
||||
const char *getPosition() const {
|
||||
assert(position);
|
||||
return position;
|
||||
}
|
||||
const char *toString() const { return representation; }
|
||||
|
||||
// Overloaded operators for bool like qualities
|
||||
operator bool() const { return flag; }
|
||||
OptionalFlag& operator=(const bool &rhs) {
|
||||
flag = rhs;
|
||||
return *this; // Return a reference to myself.
|
||||
}
|
||||
private:
|
||||
const char *representation;
|
||||
const char *position;
|
||||
bool flag;
|
||||
};
|
||||
|
||||
/// Represents the length modifier in a format string in scanf/printf.
|
||||
class LengthModifier {
|
||||
public:
|
||||
enum Kind {
|
||||
None,
|
||||
AsChar, // 'hh'
|
||||
AsShort, // 'h'
|
||||
AsLong, // 'l'
|
||||
AsLongLong, // 'll'
|
||||
AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types)
|
||||
AsIntMax, // 'j'
|
||||
AsSizeT, // 'z'
|
||||
AsPtrDiff, // 't'
|
||||
AsLongDouble, // 'L'
|
||||
AsAllocate, // for '%as', GNU extension to C90 scanf
|
||||
AsMAllocate, // for '%ms', GNU extension to scanf
|
||||
AsWideChar = AsLong // for '%ls', only makes sense for printf
|
||||
};
|
||||
|
||||
LengthModifier()
|
||||
: Position(0), kind(None) {}
|
||||
LengthModifier(const char *pos, Kind k)
|
||||
: Position(pos), kind(k) {}
|
||||
|
||||
const char *getStart() const {
|
||||
return Position;
|
||||
}
|
||||
|
||||
unsigned getLength() const {
|
||||
switch (kind) {
|
||||
default:
|
||||
return 1;
|
||||
case AsLongLong:
|
||||
case AsChar:
|
||||
return 2;
|
||||
case None:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Kind getKind() const { return kind; }
|
||||
void setKind(Kind k) { kind = k; }
|
||||
|
||||
const char *toString() const;
|
||||
|
||||
private:
|
||||
const char *Position;
|
||||
Kind kind;
|
||||
};
|
||||
|
||||
class ConversionSpecifier {
|
||||
public:
|
||||
enum Kind {
|
||||
InvalidSpecifier = 0,
|
||||
// C99 conversion specifiers.
|
||||
cArg,
|
||||
dArg,
|
||||
DArg, // Apple extension
|
||||
iArg,
|
||||
IntArgBeg = dArg, IntArgEnd = iArg,
|
||||
|
||||
oArg,
|
||||
OArg, // Apple extension
|
||||
uArg,
|
||||
UArg, // Apple extension
|
||||
xArg,
|
||||
XArg,
|
||||
UIntArgBeg = oArg, UIntArgEnd = XArg,
|
||||
|
||||
fArg,
|
||||
FArg,
|
||||
eArg,
|
||||
EArg,
|
||||
gArg,
|
||||
GArg,
|
||||
aArg,
|
||||
AArg,
|
||||
DoubleArgBeg = fArg, DoubleArgEnd = AArg,
|
||||
|
||||
sArg,
|
||||
pArg,
|
||||
nArg,
|
||||
PercentArg,
|
||||
CArg,
|
||||
SArg,
|
||||
|
||||
// ** Printf-specific **
|
||||
|
||||
// Objective-C specific specifiers.
|
||||
ObjCObjArg, // '@'
|
||||
ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
|
||||
|
||||
// GlibC specific specifiers.
|
||||
PrintErrno, // 'm'
|
||||
|
||||
PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno,
|
||||
|
||||
// ** Scanf-specific **
|
||||
ScanListArg, // '['
|
||||
ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg
|
||||
};
|
||||
|
||||
ConversionSpecifier(bool isPrintf = true)
|
||||
: IsPrintf(isPrintf), Position(0), EndScanList(0), kind(InvalidSpecifier) {}
|
||||
|
||||
ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
|
||||
: IsPrintf(isPrintf), Position(pos), EndScanList(0), kind(k) {}
|
||||
|
||||
const char *getStart() const {
|
||||
return Position;
|
||||
}
|
||||
|
||||
StringRef getCharacters() const {
|
||||
return StringRef(getStart(), getLength());
|
||||
}
|
||||
|
||||
bool consumesDataArgument() const {
|
||||
switch (kind) {
|
||||
case PrintErrno:
|
||||
assert(IsPrintf);
|
||||
return false;
|
||||
case PercentArg:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Kind getKind() const { return kind; }
|
||||
void setKind(Kind k) { kind = k; }
|
||||
unsigned getLength() const {
|
||||
return EndScanList ? EndScanList - Position : 1;
|
||||
}
|
||||
|
||||
bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; }
|
||||
bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
|
||||
bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
|
||||
const char *toString() const;
|
||||
|
||||
bool isPrintfKind() const { return IsPrintf; }
|
||||
|
||||
Optional<ConversionSpecifier> getStandardSpecifier() const;
|
||||
|
||||
protected:
|
||||
bool IsPrintf;
|
||||
const char *Position;
|
||||
const char *EndScanList;
|
||||
Kind kind;
|
||||
};
|
||||
|
||||
class ArgType {
|
||||
public:
|
||||
enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
|
||||
AnyCharTy, CStrTy, WCStrTy, WIntTy };
|
||||
private:
|
||||
const Kind K;
|
||||
QualType T;
|
||||
const char *Name;
|
||||
bool Ptr;
|
||||
public:
|
||||
ArgType(Kind k = UnknownTy, const char *n = 0) : K(k), Name(n), Ptr(false) {}
|
||||
ArgType(QualType t, const char *n = 0)
|
||||
: K(SpecificTy), T(t), Name(n), Ptr(false) {}
|
||||
ArgType(CanQualType t) : K(SpecificTy), T(t), Name(0), Ptr(false) {}
|
||||
|
||||
static ArgType Invalid() { return ArgType(InvalidTy); }
|
||||
bool isValid() const { return K != InvalidTy; }
|
||||
|
||||
/// Create an ArgType which corresponds to the type pointer to A.
|
||||
static ArgType PtrTo(const ArgType& A) {
|
||||
assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
|
||||
ArgType Res = A;
|
||||
Res.Ptr = true;
|
||||
return Res;
|
||||
}
|
||||
|
||||
bool matchesType(ASTContext &C, QualType argTy) const;
|
||||
|
||||
QualType getRepresentativeType(ASTContext &C) const;
|
||||
|
||||
std::string getRepresentativeTypeName(ASTContext &C) const;
|
||||
};
|
||||
|
||||
class OptionalAmount {
|
||||
public:
|
||||
enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
|
||||
|
||||
OptionalAmount(HowSpecified howSpecified,
|
||||
unsigned amount,
|
||||
const char *amountStart,
|
||||
unsigned amountLength,
|
||||
bool usesPositionalArg)
|
||||
: start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
|
||||
UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
|
||||
|
||||
OptionalAmount(bool valid = true)
|
||||
: start(0),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
|
||||
UsesPositionalArg(0), UsesDotPrefix(0) {}
|
||||
|
||||
bool isInvalid() const {
|
||||
return hs == Invalid;
|
||||
}
|
||||
|
||||
HowSpecified getHowSpecified() const { return hs; }
|
||||
void setHowSpecified(HowSpecified h) { hs = h; }
|
||||
|
||||
bool hasDataArgument() const { return hs == Arg; }
|
||||
|
||||
unsigned getArgIndex() const {
|
||||
assert(hasDataArgument());
|
||||
return amt;
|
||||
}
|
||||
|
||||
unsigned getConstantAmount() const {
|
||||
assert(hs == Constant);
|
||||
return amt;
|
||||
}
|
||||
|
||||
const char *getStart() const {
|
||||
// We include the . character if it is given.
|
||||
return start - UsesDotPrefix;
|
||||
}
|
||||
|
||||
unsigned getConstantLength() const {
|
||||
assert(hs == Constant);
|
||||
return length + UsesDotPrefix;
|
||||
}
|
||||
|
||||
ArgType getArgType(ASTContext &Ctx) const;
|
||||
|
||||
void toString(raw_ostream &os) const;
|
||||
|
||||
bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
|
||||
unsigned getPositionalArgIndex() const {
|
||||
assert(hasDataArgument());
|
||||
return amt + 1;
|
||||
}
|
||||
|
||||
bool usesDotPrefix() const { return UsesDotPrefix; }
|
||||
void setUsesDotPrefix() { UsesDotPrefix = true; }
|
||||
|
||||
private:
|
||||
const char *start;
|
||||
unsigned length;
|
||||
HowSpecified hs;
|
||||
unsigned amt;
|
||||
bool UsesPositionalArg : 1;
|
||||
bool UsesDotPrefix;
|
||||
};
|
||||
|
||||
|
||||
class FormatSpecifier {
|
||||
protected:
|
||||
LengthModifier LM;
|
||||
OptionalAmount FieldWidth;
|
||||
ConversionSpecifier CS;
|
||||
/// Positional arguments, an IEEE extension:
|
||||
/// IEEE Std 1003.1, 2004 Edition
|
||||
/// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
|
||||
bool UsesPositionalArg;
|
||||
unsigned argIndex;
|
||||
public:
|
||||
FormatSpecifier(bool isPrintf)
|
||||
: CS(isPrintf), UsesPositionalArg(false), argIndex(0) {}
|
||||
|
||||
void setLengthModifier(LengthModifier lm) {
|
||||
LM = lm;
|
||||
}
|
||||
|
||||
void setUsesPositionalArg() { UsesPositionalArg = true; }
|
||||
|
||||
void setArgIndex(unsigned i) {
|
||||
argIndex = i;
|
||||
}
|
||||
|
||||
unsigned getArgIndex() const {
|
||||
return argIndex;
|
||||
}
|
||||
|
||||
unsigned getPositionalArgIndex() const {
|
||||
return argIndex + 1;
|
||||
}
|
||||
|
||||
const LengthModifier &getLengthModifier() const {
|
||||
return LM;
|
||||
}
|
||||
|
||||
const OptionalAmount &getFieldWidth() const {
|
||||
return FieldWidth;
|
||||
}
|
||||
|
||||
void setFieldWidth(const OptionalAmount &Amt) {
|
||||
FieldWidth = Amt;
|
||||
}
|
||||
|
||||
bool usesPositionalArg() const { return UsesPositionalArg; }
|
||||
|
||||
bool hasValidLengthModifier(const TargetInfo &Target) const;
|
||||
|
||||
bool hasStandardLengthModifier() const;
|
||||
|
||||
Optional<LengthModifier> getCorrectedLengthModifier() const;
|
||||
|
||||
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
|
||||
|
||||
bool hasStandardLengthConversionCombination() const;
|
||||
|
||||
/// For a TypedefType QT, if it is a named integer type such as size_t,
|
||||
/// assign the appropriate value to LM and return true.
|
||||
static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM);
|
||||
};
|
||||
|
||||
} // end analyze_format_string namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// Pieces specific to fprintf format strings.
|
||||
|
||||
namespace analyze_printf {
|
||||
|
||||
class PrintfConversionSpecifier :
|
||||
public analyze_format_string::ConversionSpecifier {
|
||||
public:
|
||||
PrintfConversionSpecifier()
|
||||
: ConversionSpecifier(true, 0, InvalidSpecifier) {}
|
||||
|
||||
PrintfConversionSpecifier(const char *pos, Kind k)
|
||||
: ConversionSpecifier(true, pos, k) {}
|
||||
|
||||
bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
|
||||
bool isDoubleArg() const { return kind >= DoubleArgBeg &&
|
||||
kind <= DoubleArgEnd; }
|
||||
unsigned getLength() const {
|
||||
// Conversion specifiers currently only are represented by
|
||||
// single characters, but we be flexible.
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
|
||||
return CS->isPrintfKind();
|
||||
}
|
||||
};
|
||||
|
||||
using analyze_format_string::ArgType;
|
||||
using analyze_format_string::LengthModifier;
|
||||
using analyze_format_string::OptionalAmount;
|
||||
using analyze_format_string::OptionalFlag;
|
||||
|
||||
class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
|
||||
OptionalFlag HasThousandsGrouping; // ''', POSIX extension.
|
||||
OptionalFlag IsLeftJustified; // '-'
|
||||
OptionalFlag HasPlusPrefix; // '+'
|
||||
OptionalFlag HasSpacePrefix; // ' '
|
||||
OptionalFlag HasAlternativeForm; // '#'
|
||||
OptionalFlag HasLeadingZeroes; // '0'
|
||||
OptionalAmount Precision;
|
||||
public:
|
||||
PrintfSpecifier() :
|
||||
FormatSpecifier(/* isPrintf = */ true),
|
||||
HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"),
|
||||
HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0") {}
|
||||
|
||||
static PrintfSpecifier Parse(const char *beg, const char *end);
|
||||
|
||||
// Methods for incrementally constructing the PrintfSpecifier.
|
||||
void setConversionSpecifier(const PrintfConversionSpecifier &cs) {
|
||||
CS = cs;
|
||||
}
|
||||
void setHasThousandsGrouping(const char *position) {
|
||||
HasThousandsGrouping = true;
|
||||
HasThousandsGrouping.setPosition(position);
|
||||
}
|
||||
void setIsLeftJustified(const char *position) {
|
||||
IsLeftJustified = true;
|
||||
IsLeftJustified.setPosition(position);
|
||||
}
|
||||
void setHasPlusPrefix(const char *position) {
|
||||
HasPlusPrefix = true;
|
||||
HasPlusPrefix.setPosition(position);
|
||||
}
|
||||
void setHasSpacePrefix(const char *position) {
|
||||
HasSpacePrefix = true;
|
||||
HasSpacePrefix.setPosition(position);
|
||||
}
|
||||
void setHasAlternativeForm(const char *position) {
|
||||
HasAlternativeForm = true;
|
||||
HasAlternativeForm.setPosition(position);
|
||||
}
|
||||
void setHasLeadingZeros(const char *position) {
|
||||
HasLeadingZeroes = true;
|
||||
HasLeadingZeroes.setPosition(position);
|
||||
}
|
||||
void setUsesPositionalArg() { UsesPositionalArg = true; }
|
||||
|
||||
// Methods for querying the format specifier.
|
||||
|
||||
const PrintfConversionSpecifier &getConversionSpecifier() const {
|
||||
return cast<PrintfConversionSpecifier>(CS);
|
||||
}
|
||||
|
||||
void setPrecision(const OptionalAmount &Amt) {
|
||||
Precision = Amt;
|
||||
Precision.setUsesDotPrefix();
|
||||
}
|
||||
|
||||
const OptionalAmount &getPrecision() const {
|
||||
return Precision;
|
||||
}
|
||||
|
||||
bool consumesDataArgument() const {
|
||||
return getConversionSpecifier().consumesDataArgument();
|
||||
}
|
||||
|
||||
/// \brief Returns the builtin type that a data argument
|
||||
/// paired with this format specifier should have. This method
|
||||
/// will return null if the format specifier does not have
|
||||
/// a matching data argument or the matching argument matches
|
||||
/// more than one type.
|
||||
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
|
||||
|
||||
const OptionalFlag &hasThousandsGrouping() const {
|
||||
return HasThousandsGrouping;
|
||||
}
|
||||
const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
|
||||
const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
|
||||
const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
|
||||
const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
|
||||
const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
|
||||
bool usesPositionalArg() const { return UsesPositionalArg; }
|
||||
|
||||
/// Changes the specifier and length according to a QualType, retaining any
|
||||
/// flags or options. Returns true on success, or false when a conversion
|
||||
/// was not successful.
|
||||
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx,
|
||||
bool IsObjCLiteral);
|
||||
|
||||
void toString(raw_ostream &os) const;
|
||||
|
||||
// Validation methods - to check if any element results in undefined behavior
|
||||
bool hasValidPlusPrefix() const;
|
||||
bool hasValidAlternativeForm() const;
|
||||
bool hasValidLeadingZeros() const;
|
||||
bool hasValidSpacePrefix() const;
|
||||
bool hasValidLeftJustified() const;
|
||||
bool hasValidThousandsGroupingPrefix() const;
|
||||
|
||||
bool hasValidPrecision() const;
|
||||
bool hasValidFieldWidth() const;
|
||||
};
|
||||
} // end analyze_printf namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// Pieces specific to fscanf format strings.
|
||||
|
||||
namespace analyze_scanf {
|
||||
|
||||
class ScanfConversionSpecifier :
|
||||
public analyze_format_string::ConversionSpecifier {
|
||||
public:
|
||||
ScanfConversionSpecifier()
|
||||
: ConversionSpecifier(false, 0, InvalidSpecifier) {}
|
||||
|
||||
ScanfConversionSpecifier(const char *pos, Kind k)
|
||||
: ConversionSpecifier(false, pos, k) {}
|
||||
|
||||
void setEndScanList(const char *pos) { EndScanList = pos; }
|
||||
|
||||
static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
|
||||
return !CS->isPrintfKind();
|
||||
}
|
||||
};
|
||||
|
||||
using analyze_format_string::ArgType;
|
||||
using analyze_format_string::LengthModifier;
|
||||
using analyze_format_string::OptionalAmount;
|
||||
using analyze_format_string::OptionalFlag;
|
||||
|
||||
class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
|
||||
OptionalFlag SuppressAssignment; // '*'
|
||||
public:
|
||||
ScanfSpecifier() :
|
||||
FormatSpecifier(/* isPrintf = */ false),
|
||||
SuppressAssignment("*") {}
|
||||
|
||||
void setSuppressAssignment(const char *position) {
|
||||
SuppressAssignment = true;
|
||||
SuppressAssignment.setPosition(position);
|
||||
}
|
||||
|
||||
const OptionalFlag &getSuppressAssignment() const {
|
||||
return SuppressAssignment;
|
||||
}
|
||||
|
||||
void setConversionSpecifier(const ScanfConversionSpecifier &cs) {
|
||||
CS = cs;
|
||||
}
|
||||
|
||||
const ScanfConversionSpecifier &getConversionSpecifier() const {
|
||||
return cast<ScanfConversionSpecifier>(CS);
|
||||
}
|
||||
|
||||
bool consumesDataArgument() const {
|
||||
return CS.consumesDataArgument() && !SuppressAssignment;
|
||||
}
|
||||
|
||||
ArgType getArgType(ASTContext &Ctx) const;
|
||||
|
||||
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx);
|
||||
|
||||
void toString(raw_ostream &os) const;
|
||||
|
||||
static ScanfSpecifier Parse(const char *beg, const char *end);
|
||||
};
|
||||
|
||||
} // end analyze_scanf namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Parsing and processing of format strings (both fprintf and fscanf).
|
||||
|
||||
namespace analyze_format_string {
|
||||
|
||||
enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
|
||||
|
||||
class FormatStringHandler {
|
||||
public:
|
||||
FormatStringHandler() {}
|
||||
virtual ~FormatStringHandler();
|
||||
|
||||
virtual void HandleNullChar(const char *nullCharacter) {}
|
||||
|
||||
virtual void HandlePosition(const char *startPos, unsigned posLen) {}
|
||||
|
||||
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
|
||||
PositionContext p) {}
|
||||
|
||||
virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
|
||||
|
||||
virtual void HandleIncompleteSpecifier(const char *startSpecifier,
|
||||
unsigned specifierLen) {}
|
||||
|
||||
// Printf-specific handlers.
|
||||
|
||||
virtual bool HandleInvalidPrintfConversionSpecifier(
|
||||
const analyze_printf::PrintfSpecifier &FS,
|
||||
const char *startSpecifier,
|
||||
unsigned specifierLen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
|
||||
const char *startSpecifier,
|
||||
unsigned specifierLen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Scanf-specific handlers.
|
||||
|
||||
virtual bool HandleInvalidScanfConversionSpecifier(
|
||||
const analyze_scanf::ScanfSpecifier &FS,
|
||||
const char *startSpecifier,
|
||||
unsigned specifierLen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
|
||||
const char *startSpecifier,
|
||||
unsigned specifierLen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void HandleIncompleteScanList(const char *start, const char *end) {}
|
||||
};
|
||||
|
||||
bool ParsePrintfString(FormatStringHandler &H,
|
||||
const char *beg, const char *end, const LangOptions &LO,
|
||||
const TargetInfo &Target);
|
||||
|
||||
bool ParseScanfString(FormatStringHandler &H,
|
||||
const char *beg, const char *end, const LangOptions &LO,
|
||||
const TargetInfo &Target);
|
||||
|
||||
} // end analyze_format_string namespace
|
||||
} // end clang namespace
|
||||
#endif
|
||||
120
thirdparty/clang/include/clang/Analysis/Analyses/LiveVariables.h
vendored
Normal file
120
thirdparty/clang/include/clang/Analysis/Analyses/LiveVariables.h
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements Live Variables analysis for source-level CFGs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_LIVEVARIABLES_H
|
||||
#define LLVM_CLANG_LIVEVARIABLES_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/ImmutableSet.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CFG;
|
||||
class CFGBlock;
|
||||
class Stmt;
|
||||
class DeclRefExpr;
|
||||
class SourceManager;
|
||||
|
||||
class LiveVariables : public ManagedAnalysis {
|
||||
public:
|
||||
class LivenessValues {
|
||||
public:
|
||||
|
||||
llvm::ImmutableSet<const Stmt *> liveStmts;
|
||||
llvm::ImmutableSet<const VarDecl *> liveDecls;
|
||||
|
||||
bool equals(const LivenessValues &V) const;
|
||||
|
||||
LivenessValues()
|
||||
: liveStmts(0), liveDecls(0) {}
|
||||
|
||||
LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
|
||||
llvm::ImmutableSet<const VarDecl *> LiveDecls)
|
||||
: liveStmts(LiveStmts), liveDecls(LiveDecls) {}
|
||||
|
||||
~LivenessValues() {}
|
||||
|
||||
bool isLive(const Stmt *S) const;
|
||||
bool isLive(const VarDecl *D) const;
|
||||
|
||||
friend class LiveVariables;
|
||||
};
|
||||
|
||||
class Observer {
|
||||
virtual void anchor();
|
||||
public:
|
||||
virtual ~Observer() {}
|
||||
|
||||
/// A callback invoked right before invoking the
|
||||
/// liveness transfer function on the given statement.
|
||||
virtual void observeStmt(const Stmt *S,
|
||||
const CFGBlock *currentBlock,
|
||||
const LivenessValues& V) {}
|
||||
|
||||
/// Called when the live variables analysis registers
|
||||
/// that a variable is killed.
|
||||
virtual void observerKill(const DeclRefExpr *DR) {}
|
||||
};
|
||||
|
||||
|
||||
virtual ~LiveVariables();
|
||||
|
||||
/// Compute the liveness information for a given CFG.
|
||||
static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext,
|
||||
bool killAtAssign);
|
||||
|
||||
/// Return true if a variable is live at the end of a
|
||||
/// specified block.
|
||||
bool isLive(const CFGBlock *B, const VarDecl *D);
|
||||
|
||||
/// Returns true if a variable is live at the beginning of the
|
||||
/// the statement. This query only works if liveness information
|
||||
/// has been recorded at the statement level (see runOnAllBlocks), and
|
||||
/// only returns liveness information for block-level expressions.
|
||||
bool isLive(const Stmt *S, const VarDecl *D);
|
||||
|
||||
/// Returns true the block-level expression "value" is live
|
||||
/// before the given block-level expression (see runOnAllBlocks).
|
||||
bool isLive(const Stmt *Loc, const Stmt *StmtVal);
|
||||
|
||||
/// Print to stderr the liveness information associated with
|
||||
/// each basic block.
|
||||
void dumpBlockLiveness(const SourceManager& M);
|
||||
|
||||
void runOnAllBlocks(Observer &obs);
|
||||
|
||||
static LiveVariables *create(AnalysisDeclContext &analysisContext) {
|
||||
return computeLiveness(analysisContext, true);
|
||||
}
|
||||
|
||||
static const void *getTag();
|
||||
|
||||
private:
|
||||
LiveVariables(void *impl);
|
||||
void *impl;
|
||||
};
|
||||
|
||||
class RelaxedLiveVariables : public LiveVariables {
|
||||
public:
|
||||
static LiveVariables *create(AnalysisDeclContext &analysisContext) {
|
||||
return computeLiveness(analysisContext, false);
|
||||
}
|
||||
|
||||
static const void *getTag();
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
111
thirdparty/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h
vendored
Normal file
111
thirdparty/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
//===- PostOrderCFGView.h - Post order view of CFG blocks ---------*- C++ --*-//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements post order view of the blocks in a CFG.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_POSTORDER_CFGVIEW
|
||||
#define LLVM_CLANG_POSTORDER_CFGVIEW
|
||||
|
||||
#include <vector>
|
||||
//#include <algorithm>
|
||||
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class PostOrderCFGView : public ManagedAnalysis {
|
||||
virtual void anchor();
|
||||
public:
|
||||
/// \brief Implements a set of CFGBlocks using a BitVector.
|
||||
///
|
||||
/// This class contains a minimal interface, primarily dictated by the SetType
|
||||
/// template parameter of the llvm::po_iterator template, as used with
|
||||
/// external storage. We also use this set to keep track of which CFGBlocks we
|
||||
/// visit during the analysis.
|
||||
class CFGBlockSet {
|
||||
llvm::BitVector VisitedBlockIDs;
|
||||
public:
|
||||
// po_iterator requires this iterator, but the only interface needed is the
|
||||
// value_type typedef.
|
||||
struct iterator { typedef const CFGBlock *value_type; };
|
||||
|
||||
CFGBlockSet() {}
|
||||
CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {}
|
||||
|
||||
/// \brief Set the bit associated with a particular CFGBlock.
|
||||
/// This is the important method for the SetType template parameter.
|
||||
bool insert(const CFGBlock *Block) {
|
||||
// Note that insert() is called by po_iterator, which doesn't check to
|
||||
// make sure that Block is non-null. Moreover, the CFGBlock iterator will
|
||||
// occasionally hand out null pointers for pruned edges, so we catch those
|
||||
// here.
|
||||
if (Block == 0)
|
||||
return false; // if an edge is trivially false.
|
||||
if (VisitedBlockIDs.test(Block->getBlockID()))
|
||||
return false;
|
||||
VisitedBlockIDs.set(Block->getBlockID());
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Check if the bit for a CFGBlock has been already set.
|
||||
/// This method is for tracking visited blocks in the main threadsafety
|
||||
/// loop. Block must not be null.
|
||||
bool alreadySet(const CFGBlock *Block) {
|
||||
return VisitedBlockIDs.test(Block->getBlockID());
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
typedef llvm::po_iterator<const CFG*, CFGBlockSet, true> po_iterator;
|
||||
std::vector<const CFGBlock*> Blocks;
|
||||
|
||||
typedef llvm::DenseMap<const CFGBlock *, unsigned> BlockOrderTy;
|
||||
BlockOrderTy BlockOrder;
|
||||
|
||||
public:
|
||||
typedef std::vector<const CFGBlock*>::reverse_iterator iterator;
|
||||
|
||||
PostOrderCFGView(const CFG *cfg);
|
||||
|
||||
iterator begin() { return Blocks.rbegin(); }
|
||||
iterator end() { return Blocks.rend(); }
|
||||
|
||||
bool empty() { return begin() == end(); }
|
||||
|
||||
struct BlockOrderCompare;
|
||||
friend struct BlockOrderCompare;
|
||||
|
||||
struct BlockOrderCompare {
|
||||
const PostOrderCFGView &POV;
|
||||
public:
|
||||
BlockOrderCompare(const PostOrderCFGView &pov) : POV(pov) {}
|
||||
bool operator()(const CFGBlock *b1, const CFGBlock *b2) const;
|
||||
};
|
||||
|
||||
BlockOrderCompare getComparator() const {
|
||||
return BlockOrderCompare(*this);
|
||||
}
|
||||
|
||||
// Used by AnalyisContext to construct this object.
|
||||
static const void *getTag();
|
||||
|
||||
static PostOrderCFGView *create(AnalysisDeclContext &analysisContext);
|
||||
};
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user